【问题标题】:EF 4.1 Code First: Many to ManyEF 4.1 代码优先:多对多
【发布时间】:2013-05-18 16:17:35
【问题描述】:

我有 2 个实体,比如说 A 和 B。它们之间的关系是多对多的,所以我有另一个实体,比如说 C。

表 A 的列:
-Id (PK) -> 输入数据库生成的 int
-PropertyA1
-PropertyA2
-PropertyA3

表 B 的列:
-Id (PK) -> 输入数据库生成的 int
-描述

表 C 的列(对于这个表,我不确定是否最好添加一个由数据库生成的额外列 ID 作为以前的表):
-IdA(PK 以及实体 A 的外键)
-IdB(PK 以及实体 B 的外键)

表 B 具有在种子方法中插入的固定值(被覆盖)。它的条目如下:
标识说明
1“一些描述1”
2“一些描述2”
3 “一些描述 3”

用户从一个表单中引入与表A相关的信息(propertyA1,...,propeprtyA3),然后点击一个按钮将数据保存到数据库中。

一旦用户点击按钮的表单将数据保存到数据库中,首先我会执行以下操作:

   A a = new A(){ PropertyA1=something_1,
                  PropertyA2=something_2,
                  PropertyA3=something_3 };

   context.A.Add(a);
   context.SaveChanges();

那么在将更改保存到数据库之后,我有数据库生成的Id(在保存到数据库之前我没有id),即a.Id,现在我可以继续向表C添加一个条目:

  B b = this.ObtainAppropriateB();
  C c = new C(){ IdA = a.Id,
                 IdB = b.Id };

  context.C.Add(c);
  context.SaveChanges();

我的问题是:
1) 我无法知道之前的 a.Id 以在 context.A.Add(a) 之后执行 context.SaveChanges,因为它是由数据库生成的。
2) 如果 context.C.Add(c) 之后 context.SaveChanges 失败,我该如何回滚之前的工作?:
上下文.A.Add(a);
context.SaveChanges();

我无法执行以下操作,因为我之前没有 a.Id 来执行 SaveChanges:

   A a = new A(){ PropertyA1=something_1,
                  PropertyA2=something_2,
                  PropertyA3=something_3 };

   context.A.Add(a);
   B b = this.ObtainAppropriateB();
   C c = new C(){ IdA = a.Id,
                  IdB = b.Id };

   context.C.Add(c);

   context.SaveChanges(); <--- I call it once to persist changes to database

如何解决?

【问题讨论】:

  • 你是说A和B的关系是many-to-many
  • 是的,有什么问题?

标签: c# entity-framework ef-code-first


【解决方案1】:

这不是您使用 Entity Framework 处理多对多关系的方式。

首先,您的模型中不应有 C 实体,而是实体 AB 上的集合属性:

public class A
{
    public int AId { get; set; }
    public int PropertyA1 { get; set; }
    public string PropertyA2 { get; set; }
    public DateTime PropertyA3 { get; set; }

    public ICollection<B> Bs { get; set; }
}

public class B
{
    public int BId { get; set; }

    // ...

    public ICollection<A> As { get; set; }
}

从集合中,EF 能够确定关系是多对多的,并且需要一个链接表 (C)。您可以使用 Fluent API 定义映射细节。

其次,一旦你有了导航集合,你就不需要关心 Id。您只需构建具有必要关系的对象图并将其保存到数据库中:

A a = new A() { PropertyA1 = something_1,
                PropertyA2 = something_2,
                PropertyA3 = something_3 };
a.Bs = new List<B>();

B b = this.ObtainAppropriateB(); // must use same context instance

a.Bs.Add(b);

context.A.Add(a);
context.SaveChanges();

它将创建一个新的A,并将ab之间的关系行插入到链接表中。

【讨论】:

  • 谢谢,它有效。正如 Carlos Company 上面所说的,我在考虑数据库术语而不是模型术语。我还是 EF 代码的新手...谢谢大家!
【解决方案2】:

我认为问题在于您考虑的是数据库术语而不是模型术语。您应该忘记表 C,因为该表将由数据库生成。您应该在 A 类中有一个 B 的集合,在 B 类中有一个 A 的集合。然后指定多对多关系。如果将 B 添加到 A,并保存上下文,则适当的数据将添加到表 C。

【讨论】:

  • 你说得对,我在考虑数据库术语而不是模型术语。我还是 EF 代码的新手...谢谢大家!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-02
  • 2012-09-18
  • 1970-01-01
相关资源
最近更新 更多