EF 4.1 代码优先:多对多
Posted
技术标签:
【中文标题】EF 4.1 代码优先:多对多【英文标题】:EF 4.1 Code First: Many to Many 【发布时间】: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
?
是的,有什么问题?
【参考方案1】:
这不是您使用 Entity Framework 处理多对多关系的方式。
首先,您的模型中不应有 C
实体,而是实体 A
和 B
上的集合属性:
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
,并将a
和b
之间的关系行插入到链接表中。
【讨论】:
谢谢,它有效。正如 Carlos Company 上面所说的,我在考虑数据库术语而不是模型术语。我还是 EF 代码的新手...谢谢大家!【参考方案2】:我认为问题在于您考虑的是数据库术语而不是模型术语。您应该忘记表 C,因为该表将由数据库生成。您应该在 A 类中有一个 B 的集合,在 B 类中有一个 A 的集合。然后指定多对多关系。如果将 B 添加到 A,并保存上下文,则适当的数据将添加到表 C。
【讨论】:
你说得对,我在考虑数据库术语而不是模型术语。我还是 EF 代码的新手...谢谢大家!以上是关于EF 4.1 代码优先:多对多的主要内容,如果未能解决你的问题,请参考以下文章
使用 EF4 CTP4 代码优先方法生成的多对多表中的命名约定
如何使用 MVC3 多对多关系和 EF4.1 模型优先检索数据?