【问题标题】:MVC implementation of many to many relationshipsMVC实现多对多关系
【发布时间】:2018-11-29 14:57:41
【问题描述】:

这是使用 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; }
}

First 和 Second 表有一些作为主键的 id。

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

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

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

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

【问题讨论】:

  • 一旦您开始添加与严格的多对多无关的列,即“public int something {get;set;}”。您正在创建一个新实体,它应该被映射为一对多 - 多对一的关系。

标签: asp.net-mvc entity-framework many-to-many master-detail


【解决方案1】:

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 中创建一个映射表。通常Mapping表只包含其他两个表的主键。

您可以使用 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; }
} 

【讨论】:

  • 我不清楚,表格是这样实现的。我只是不知道如何以 Master Detail 的形式创建视图和 Action,例如 Create 或 update,其中 First Table 是 Master,second 是 details。
  • 我希望你的 MVC 端和数据层端有单独的数据模型。上面的代码只显示了数据层中的实体。在 MVC 方面,您可以创建一个单独的视图模型,该模型具有从用户那里捕获详细信息所需的所有属性。单击保存按钮时,您必须验证视图模型并将其映射到适当的实体模型并保存到数据库 context.FirstTable.Add(new FirstTable { prop1= model.M1 , prop2 = model.M2}); context.SecondTable.Add(new SecondTable{ prop1= model.D1 , prop2 = model.D2} ); context.SaveChanges()
  • 感谢您的建议。不,我没有将它们分开,看来这在 EF MVC 组合中并没有很好地计划。我曾经在 Oracle 工作,可以在几秒钟内完成主要细节。所以,我很困惑在 .net mvc 中实现同样的事情是多么困难。它需要这么多帮手...
猜你喜欢
  • 2017-04-08
  • 1970-01-01
  • 2012-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多