EF 4.1代码第一:多对多 [英] EF 4.1 Code First: Many to Many

查看:110
本文介绍了EF 4.1代码第一:多对多的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



表A的列:

-Id(PK) - >由数据库生成的int类型

-PropertyA1

-PropertyA2

-PropertyA3



表B的列:

-Id(PK) - >数据库生成的int类型

- 描述



表C的列(对于此表,我不知道是否更好地添加额外的列数据由数据库生成的前一个表):

-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的条目:

  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.A.Add(a),因为它是由数据库生成的。上下文.saveChanges。

2)如果context.CaveChanges在context.C.Add(c)之后失败,那么我如何回滚以前的工作完成了:

context.A.Add(a);

context.SaveChanges();



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

  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(); < ---我叫它一次持续更改数据库

如何解决这个问题? p>

解决方案

这不是您与Entity Framework进行多对多关系的方式。



首先,你不应该在你的模型中有一个 C 实体,而是实体 A B

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

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

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

// ...

public ICollection< A>作为{get;组; }
}

从集合EF可以看出,需要链接表( C )。您可以使用Fluent API定义映射详细信息。



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

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

B b = this.ObtainAppropriateB(); //必须使用相同的上下文实例

a.Bs.Add(b);

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

它将创建一个新的 A 并插入 a b 之间的关系行进入链接表。


I have 2 entities, let's say A and B. Relation between them is many-to-many so I have another entity, let's say C.

Columns for table A:
-Id (PK) -> Type int generated by database
-PropertyA1
-PropertyA2
-PropertyA3

Columns for table B:
-Id (PK) -> Type int generated by database
-Description

Columns for table C (For this table I am not sure if it is better to add an extra column Id generated by database as previous tables):
-IdA (PK and also foreign key to entity A)
-IdB (PK and also foreign key to entity B)

Table B has fixed values that are inserted on seed method (overrided). Its entries are like below:
Id Description
1 "Some description 1"
2 "Some description 2"
3 "Some description 3"

From a form, user introduces the information related to table A (propertyA1,...,propeprtyA3) and then click on a button to save the data to the database.

Once user clicks on button's form to save data into database, first I do the following:

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

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

then as after saving changes to database I have the Id generated by database (I have not id before saving to database), that is, a.Id, now I can proceed to add an entry to table C by doing:

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

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

My problem is:
1) I cannot know a.Id previous to do context.SaveChanges after context.A.Add(a) because it is generated by database.
2) If context.SaveChanges fails after context.C.Add(c), how can I rollback as well previous work done?:
context.A.Add(a);
context.SaveChanges();

I cannot do the following because I have not a.Id previous to do 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

How to solve this?

解决方案

This is not the way you work with a many-to-many relationship with Entity Framework.

First, you should not have a C entity in your model but instead collection properties on entity A and 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; }
}

From the collections EF is able to figure out that the relationship is many-to-many and that a link table (C) is needed. You can define the mapping details with Fluent API.

Second, once you have the navigation collections you don't need to care about the Ids. You just build an object graph with the necessary relationships and save it to the database:

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();

It will create a new A and insert the relationship row between a and b into the link table.

这篇关于EF 4.1代码第一:多对多的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆