首页 > 解决方案 > MVC实现多对多关系

问题描述

这是使用 MVC .net 框架和实体框架“数据库优先”方法完成的。两个表之间存在多对多关系。它们通过第三个表连接,该表具有组合键作为第一个表的 id 和第二个表的 id。

  public class ManyToManyTable
  {
    [Required]
    [Key, Column(Order=0)]
    public int firsttableid { get; set; }

    [Required]
    [Key, Column(Order=1)]
    public int secondtableid { get; set; }

    public int something { get; set; }

    [ForeignKey("firsttableid")]
    public virtual FirstTable firstTable { get; set; }

    [ForeignKey("secondtableid")]
    public virtual SecondTable secondTable { get; set; }
}

第一个和第二个表有一些作为主键的 id。

我想创建视图和控制器方法,为这个 ManyToManyTable 启用主详细信息输入表单。这将在 Master 和 SecondTable 中有 FirstTable 的详细信息,并且当按下 Save 按钮时所有内容都将保存在 ManyToManyTable 中。

当然,First Table 和 Second Table 都有这个属性:

public virtual ICollection<ManyToManyTable> ManyToManyTables { get; set; }

实施此类案例的最简单方法是什么?谢谢!

标签: asp.net-mvcentity-frameworkmany-to-manymaster-detail

解决方案


EF 具有多对多关系的默认约定。无需创建特定的
映射类。您必须在“FirstTable”和“SecondTable”类中包含导航属性,如下所示。

 public class FirstTable
{
    public FirstTable()
    {
        secondTableProperties = new HashSet<SecondTable>();
    }
    public int Id { get; set; }
    public int MyProperty2 { get; set; }
    public int MyProperty3 { get; set; }
    public virtual ICollection<SecondTable> secondTableProperties  { get; set; }
}

public class SecondTable
{
public SecondTable()
{
        FirstTableProperties = new HashSet<FirstTable>();
}
public int Id { get; set; }
public int MyProperty2 { get; set; }
public int MyProperty3 { get; set; }
public virtual ICollection<FirstTable> FirstTableProperties { get; set; }
}

从 DBContext 中移除映射类,只包含以上两个类。构建并运行应用程序,EF 会自动在 SQL Server 中创建一个映射表。通常映射表只包含其他两个表的主键。

您可以使用 Fluent API 对创建的映射表进行一些控制

modelBuilder.Entity<FirstTable>()
            .HasMany<SecondTable>(s => s.FirstTableProperties)
            .WithMany(c => c.secondTableProperties)
            .Map(cs =>
                    {
                        cs.MapLeftKey("FirstTableId");
                        cs.MapRightKey("SecondTableId");
                        cs.ToTable("ManyToManyTable");
                    });

如果您想使用具有附加属性的连接表,上述多对多关系将不起作用。在这种情况下,您将必须创建两个一对多关系,如下所示。

public class FirstTable
{
    public int Id { get; set; }
    public int MyProperty2 { get; set; }
    public virtual ICollection<ManyToManyTable> manytomany { get; set; }
}

public class SecondTable
{
public int Id { get; set; }
public int MyProperty2 { get; set; }
public virtual ICollection<ManyToManyTable> manytomany { get; set; }
}

public ManyToManyTable
{
[Required]
[Key, Column(Order=0)]
public int firsttableid { get; set; }
[Required]
[Key, Column(Order=1)]
public int secondtableid { get; set; }
public int AdditionalProperty { get; set; }
public virtual FirstTable first { get; set; }
public virtual SecondTable Second { get; set; }
} 

推荐阅读