使用现有对象插入新对象

时间:2011-03-24 08:04:35

标签: c# .net entity-framework entity-framework-4

我是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已经存在于数据库中! (我从组合框中选择了这个。)

这就是我填充组合框的方式:

在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,我该怎么办?

2 个答案:

答案 0 :(得分:19)

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

  • 在将数据库添加到objectB之前从数据库加载objectA。在这种情况下,EF将知道objectB是现有对象,并且不会再次插入它。
  • objectB附加到上下文,然后再将其添加到objectAObjectB将按现有方式处理,但不会更改。
  • 插入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;

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

希望得到这个帮助。