使用现有对象插入新对象

我是EF 4的新手,这是我到目前为止所做的:

  • 根据我的数据库创建edmx文件
  • 为我的对象(PO​​CO)创建代码生成。 现在我有了一个model1.tt,扩展后我会看到我的课程
  • 基于IRepository为每个类创建一个存储库

现在,我正在处理两个对象,A和B.对象A具有类型B的属性。在我的winform中,我有一个组合填充了类型B的对象。当按下保存按钮时,A类的新实例是创建并设置所有属性。 对象B属性设置如下:

objectA.myObjectB = (objectB)cmbBObjects.selectedItem; 

然后我为objectA创建一个存储库并调用save方法。 在这个保存方法中,我有这个代码±

 public bool Save(ObjectA obj) { using(MyContext context = new MyContext()) { context.objectAs.AddObject(obj); context.SaveChanges(); } } 

这段代码确实为数据库保存了一个新条目,但它也为对象B创建了一个新记录! 我不想要这个,因为对象B已经存在于数据库中! (我从combobox中选择了这个)。

这就是我填充combobox的方式:

在objectB存储库中:

 public IList GetAll() { using(MyContext context = new MyContext()) { IList objects = context.objectBs.ToList(); return objects; } } 

在我的forms:

 ObjectBRepository rep = new ObjectBRepository(); IList objects = rep.GetAll; cmbBObjects.Datasource = objects; // etc.. 

所以我的问题是,如何在不为objectB创建新记录的情况下保存对象A?

如果您不想插入objectB ,则必须通知EF。 当你为objectA调用context.objectAs.AddObject(obj) ,你会说: 我想插入objectA及其所有依赖项 。 但显然你不想保存家属,所以你必须:

  • 在将objectA添加到objectA之前从DB加载objectA 。 在这种情况下,EF将知道objectB是现有对象,并且它不会再次插入它。
  • 在将objectB添加到objectA之前将objectB附加到上下文。 ObjectB将作为现有处理但未更改。
  • 插入objectA后设置objectB的状态。 你可以通过调用: context.ObjectStateManager.ChangeObjectState(objectB, EntityState.Unchanged)来做到这一点。

第一个建议的例子:

 var id = objectB.Id; objectA.myObjectB = context.ObjectBs.SingleOrDefault(o => o.Id == id); 

第二个建议的例子:

 context.ObjectBs.Attach(objectB); objectA.myObjectB = objectB; 

第三个建议的例子:

 objectA.myObjectB = objectB; context.ObjectAs.AddObject(objectA); context.ObjectStateManager.ChangeObjectState(objectB, EntityState.Unchanged); 

我想下一行中的问题:

 objectA.myObjectB = (objectB)cmbBObjects.selectedItem; 

由于结果(objectB)cmbBObjects.selectedItem与datacontextentity framework分离,因此创建新实例。 相反,你可以:

1.将objectB id分配给objectA

 var b = (objectB)cmbBObjects.selectedItem; objectA.myObjectBId = b.Id; 

2.或者从dataContext加载objectB,然后分配给objectA:

 var b = (objectB)cmbBObjects.selectedItem; var dcB = context.ObjectBs.Single(x=> x.Id == b.Id); objectA.myObjectB = dcB; 

试试我的建议然后回来看结果,因为我不确切知道。

希望这有帮助。