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与另外两个实体有关系的实体:Trainer和Horse.
我从外部源获取数据,因此我必须手动创建所有实体.
每次我需要插入一个新的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调用时,只能在数据库中修改这些实体.每个这样的实体拥有ObjectStateEntry的ObjectStateManager.其中一个主要特性ObjectStateEntry是a State.状态为枚举类型EntityState,提供以下值:
从数据库加载的每个实体都处于Unchanged状态.分离是特殊状态.您将找不到ObjectStateEntry具有分离状态的ObjectStateManager.但是如果你要求上下文不跟踪ObjectStateManager的ObjectStateEntryfor实体,它将创建一个新的ObjectStateEntrywith Detached状态.
现在区别Attach和AddObject:
Attach- 如果你调用此方法ObjectContext将开始跟踪整个对象图(主要实体和所有相关实体).尚未跟踪的所有实体将设置为Unchanged州.AddObject- 如果你调用此方法ObjectContext也将开始跟踪整个对象图(主要实体和所有相关实体).不同之处在于,尚未跟踪的所有实体都将设置为Addedstate(=必须设置为数据库的新对象).小智 9
我知道我对这篇文章有点晚了,但是正在寻找类似的解决方案......然后我发现这篇微软的文章可能会简洁地回答OP的大部分问题,并可能有助于未来的SO观众?:
添加/附加和实体状态 ==(http://msdn.microsoft.com/en-us/data/jj592676.aspx)
来自文章:
本主题将介绍如何在上下文中添加和附加实体,以及Entity Framework如何在SaveChanges期间处理这些实体.
具体请参见该页面的最后一节:
插入或更新模式: 某些应用程序的常见模式是将实体添加为新实体(导致数据库插入)或将实体附加为现有实体并将其标记为已修改(导致数据库更新),具体取决于首要的关键.