EF 4.1 Code First:多对多

时间:2013-05-18 16:17:36

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

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

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

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

表C的列(对于此表,我不确定是否更好地添加由数据库生成的额外列Id作为前面的表):
-IdA(PK和实体A的外键)
-IdB(PK和实体B的外键)

表B具有在种子方法上插入的固定值(覆盖)。其条目如下:
Id说明
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添加一个条目: / p>

  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失败了,我怎么能回滚以前完成的工作?:
              context.A.Add(一);
              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

如何解决这个问题?

2 个答案:

答案 0 :(得分:5)

这不是您使用与实体框架建立多对多关系的方式。

首先,您的模型中不应该有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之间的关系行插入到链接表中。

答案 1 :(得分:1)

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