我是EF 4的新手,这是我到目前为止所做的:
现在,我正在使用两个对象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已经存在于数据库中! (我从组合框中选择了这个。)
这就是我填充组合框的方式:
在objectB存储库中:
public IList<ObjectB> GetAll()
{
using(MyContext context = new MyContext())
{
IList<ObjectB> objects = context.objectBs.ToList();
return objects;
}
}
以我的形式:
ObjectBRepository rep = new ObjectBRepository();
IList<ObjectB> objects = rep.GetAll;
cmbBObjects.Datasource = objects;
// etc..
所以我的问题是,如何在不为objectB创建新记录的情况下保存对象A,我该怎么办?
答案 0 :(得分:19)
如果您不想插入objectB
,则必须告知EF。当您为context.objectAs.AddObject(obj)
致电objectA
时,您会说:我想插入objectA及其所有依赖项。但显然你不想保存家属,所以你必须:
objectB
之前从数据库加载objectA
。在这种情况下,EF将知道objectB
是现有对象,并且不会再次插入它。objectB
附加到上下文,然后再将其添加到objectA
。 ObjectB
将按现有方式处理,但不会更改。objectB
后设置objectA
的状态。您可以致电: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);
答案 1 :(得分:1)
我认为下一行存在问题:
objectA.myObjectB = (objectB)cmbBObjects.selectedItem;
由于结果(objectB)cmbBObjects.selectedItem
与datacontext实体框架分离,因此创建新实例。相反,你可以:
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;
试试我的建议然后回来看结果,因为我不确切知道。
希望得到这个帮助。