将新对象插入现有对象

发布于 2024-10-27 01:41:58 字数 1166 浏览 2 评论 0原文

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

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

现在,我正在使用两个对象 A 和 B。对象 A 具有类型 B 的属性。在我的 winform 中我有一个充满 B 类型对象的组合。按下保存按钮时,将创建 A 类的新实例并设置所有属性。对象 B 属性设置如下:

objectA.myObjectB = (objectB)cmbBObjects.selectedItem;

然后我为对象 A 创建一个存储库并调用 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..

所以我的问题是,我必须做什么才能保存对象 A 而不为 objectB 创建新记录?

I am new to EF 4 and this is what I have done so far:

  • Create an edmx file based on my database
  • Create a code generation for my objects (POCO). Now I have a model1.tt, when expanded I see al my classes
  • Create a repository for each class, based on IRepository

Now, I am working with two objects, A and B. Object A has a property of type B. In my winform I have a combo filled with objects of type B. When the save button is pressed, a new instance of class A is created and all the properties are set. The object B property is set as follows:

objectA.myObjectB = (objectB)cmbBObjects.selectedItem;

Then I create a repository for objectA and call the save method. In this save method I have this code±

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

This code, does save a new entry to the database, but it is also creating a new record for object B! I don't want this, because object B already exists in the database! (I have selected this one from the combobox).

This is how I fill my combobox:

In the objectB repository:

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

In my form:

ObjectBRepository rep = new ObjectBRepository();
IList<ObjectB> objects = rep.GetAll;

cmbBObjects.Datasource = objects;
// etc..

So my question is, what do I have to do to save object A without creating a new record for objectB?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

思慕 2024-11-03 01:41:58

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

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

If you don't want insert objectB you must inform EF about it. When you call context.objectAs.AddObject(obj) for objectA you are saying: I want to insert objectA and all its dependencies. But obviously you don't want to save dependecies so you must either:

  • Load objectB from DB before adding it to objectA. In such case EF will know that objectB is existing object and it will not insert it again.
  • Attach objectB to context before adding it to objectA. ObjectB will be handled as existing but unchanged.
  • Set the state of objectB after inserting objectA. You can do that by calling: context.ObjectStateManager.ChangeObjectState(objectB, EntityState.Unchanged)

Example of the fist suggestion:

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

Example of the second suggestion:

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

Example of the third suggestion:

objectA.myObjectB = objectB;
context.ObjectAs.AddObject(objectA);
context.ObjectStateManager.ChangeObjectState(objectB, EntityState.Unchanged);
醉梦枕江山 2024-11-03 01:41:58

我认为该问题出现在以下行中:

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;

只需尝试我的建议并返回结果,因为我不确切知道。

希望这有帮助。

I suppose that problem in following row:

objectA.myObjectB = (objectB)cmbBObjects.selectedItem;

Because of result (objectB)cmbBObjects.selectedItem detached from datacontext entity framework create new instance. Instead this you can:

1.Assign objectB id to objectA

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

2.Or load objectB from dataContext and than assign to objectA:

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

Just try my suggestions and come back with results, because i don't know exactly.

Hope this help.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文