通过导航添加项目并在新上下文中存储

时间:2014-01-10 16:05:19

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

我开始使用EF4并且很难理解我应该如何正确添加对象。 这是一个多层应用程序,我有一个datalayer,它返回我的实体。然后,我在业务层中更改该实体,并通过导航将对象添加到其链接对象。但是,当我尝试更新实体时,我似乎遇到了一个问题,当添加相关对象时。

所以我有这样的事情:

FirstTypeOfObject:Id,SomeProperty SecondTypeOfObject:Id,SomeProperty,FKToFirstTypeOfObject ThirdTypeOfObject:Id,SomeProperty,FKToSecondTypeOfObject

所以我有一对多的关系。

现在在我的DAL中,我检索到FirstTypeOfObject:

using(var context = new ObjectContext())
{
  var first = context.FirstTypeOfObjects
    .Single(i => i.id = "something")
    .Include(o => o.SecondTypeOfObjects.Select(s => s.ThirdKindOfObjects))) 
  return first;
}

然后我在我的businesslayer中添加到这个对象:

ThirdKindOfObject t = new ThirdKindOfObject();
t.SomeProperty = "test";
t.Id = Guid.NewGuid();
first.SecondTypeOfObjects.FirstOrDefault().Add(t);

然后我在DAL中调用一个方法:

public void UpdateObject(FirstTypeOfObject myObject)
{
  using(var context = new ObjectContext())
  {
    context.FirstTypeOfObject.Attach(myObject)
    context.ObjectStateManager.ChangeObjectState(myObject, EntityState.Modified);
    context.SaveChanges()
  }
}

但是当我更新项目时出现错误:

An object with a temporary EntityKey value cannot be attached to an object context

每次我需要创建一个ThirdTypeOfObject时,我都不想去数据库,因为它可能是100个对象。另外,我想传递实体模型进行修改,而我的DAL不知道修改了什么。我不希望我的DAL知道业务层中编写的任何类。

我这样做是因为它不是故意的吗?我只是错过了什么?

1 个答案:

答案 0 :(得分:1)

  

另外,我想传递实体模型进行修改,而我的DAL并不知道修改了什么。我不希望我的DAL知道在业务层中编写的任何类。

     

我这样做是因为它没有意图吗?我只是错过了什么?

您应该为每个HTTP请求使用一个数据库上下文,而不是微管理数据库上下文,即在DAL层的每个方法中打开和关闭新上下文。然后,数据库上下文将跟踪给定HTTP请求中的所有更改。 ObjectContext实际上是Unit of Work的实现,使用dependency injection container可以将工作单元的生命周期设置为HTTP请求的范围。这将消除断开连接的实体,这可能是您发现的麻烦。

根据您的体系结构,您希望将更改保存到业务层上方的图层中。