在实体框架中,添加和附加有什么区别,我该如何解决我的问题?

Osc*_*ros 16 c# entity-framework

我最近开始使用实体框架,检查我是否真的需要向数据库添加新记录是一件很痛苦的事情.

如果我需要添加到数据库的实体已经在它上面,我会知道,因为我在插入之前进行查询,如果存在,那么我保留该实例,因为我需要在某些关系中使用它.

我们假设我的实体名称是Book.

当一个实体不在数据库中时,问题出现了,我这样做:

Book b = //...
modelContainer.AddToBooks(b);
Run Code Online (Sandbox Code Playgroud)

我很容易做到:

modelContainer.SaveChanges()
Run Code Online (Sandbox Code Playgroud)

每次我添加一个新实体(无论它是什么实体),这都可以正常工作,因为我一次插入一种条目,并检查它是否已经在数据库中,我不会有重复问题.

但是,如果我想避免SaveChanges()经常打电话怎么办?

在这个问题中:是否可以检查对象是否已附加到实体框架中的数据上下文?,问题的作者提供了一种方法,在我的情况下可以帮助我,但如果我Add是上下文的对象而不是Attaching它,它就不起作用.

我的问题(可能是两个,但非常相关)是:添加和附加有什么区别,我该如何解决我的问题?

编辑:
这是我遇到的问题的一个例子.

我有一个Result与另外两个实体有关系的实体:TrainerHorse.

我从外部源获取数据,因此我必须手动创建所有实体.

每次我需要插入一个新的Trainer,我做:

var trainer = Trainer.CreateTrainer(Id)
Run Code Online (Sandbox Code Playgroud)

然后我查询数据库以查看具有该数据库的培训师Id是否已经在数据库中.如果是,那么我将trainer变量替换为数据库中的变量.

如果不是,我可以在这做两件事:

  • 将培训师附加到上下文(我可以使用密钥检查它是否已存在)
  • 将培训师添加到上下文中(使用AddToTrainers(...))

同样的过程Horse.

现在,当我需要创建一个新的Result(包含a Trainer和a Horse)时,我将前一个培训师和马分配给该结果实例.

我该怎么做才能添加新的上下文Result

  • 如果我附上训练师/马,那么当我附上结果时,我会InvalidOperationException告诉我,训练师已经在对象背景下.
  • 如果我添加培训师而不是附加它,我会收到另一个错误(现在不能记住它,但它告诉我培训师已经在数据库中了).

重要提示:
附加结果时会出现第一个错误,执行时会出现第二个错误SaveChanges().

我想在这里避免的是SaveChanges()每次添加新结果时调用.

Lad*_*nka 21

ObjectContext内部跟踪由上下文加载,附加或添加的所有实体.SaveChanges调用时,只能在数据库中修改这些实体.每个这样的实体拥有ObjectStateEntryObjectStateManager.其中一个主要特性ObjectStateEntry是a State.状态为枚举类型EntityState,提供以下值:

  • 添加
  • 删除
  • 超脱
  • 改性
  • 不变

从数据库加载的每个实体都处于Unchanged状态.分离是特殊状态.您将找不到ObjectStateEntry具有分离状态的ObjectStateManager.但是如果你要求上下文不跟踪ObjectStateManagerObjectStateEntryfor实体,它将创建一个新的ObjectStateEntrywith Detached状态.

现在区别AttachAddObject:

  • Attach- 如果你调用此方法ObjectContext将开始跟踪整个对象图(主要实体和所有相关实体).尚未跟踪的所有实体将设置为Unchanged州.
  • AddObject- 如果你调用此方法ObjectContext也将开始跟踪整个对象图(主要实体和所有相关实体).不同之处在于,尚未跟踪的所有实体都将设置为Addedstate(=必须设置为数据库的新对象).


小智 9

我知道我对这篇文章有点晚了,但是正在寻找类似的解决方案......然后我发现这篇微软的文章可能会简洁地回答OP的大部分问题,并可能有助于未来的SO观众?:

添加/附加和实体状态 ==(http://msdn.microsoft.com/en-us/data/jj592676.aspx)

来自文章:

本主题将介绍如何在上下文中添加和附加实体,以及Entity Framework如何在SaveChanges期间处理这些实体.

具体请参见该页面的最后一节:

插入或更新模式: 某些应用程序的常见模式是将实体添加为新实体(导致数据库插入)或将实体附加为现有实体并将其标记为已修改(导致数据库更新),具体取决于首要的关键.