问题描述
我最近开始使用实体框架,它一直很痛苦的检查,如果我真的需要新的记录添加到数据库或没有。
I recently started using Entity Framework, and it has been kind of a pain to check if I really need to add new records to the database or not.
如果在实体的我需要插入之前加入到数据库中已经打开它,我就知道了,因为我做了查询,如果存在的话,那么我把这个实例,因为我需要使用它在一些关系。
If the Entity I need to add to the database is already on it, I will know, because I do a query before inserting it, and if it exists, then I keep that instance because I need to use it in some relationships.
让我们假设我的实体名称为图书
。
Let's suppose my entity name is Book
.
问题是当一个实体是不是在数据库中,和我做的:
The problem comes when an entity isn't in the database, and I do:
Book b = //...
modelContainer.AddToBooks(b);
我可以很容易做的:
I could easily do:
modelContainer.SaveChanges()
我每次添加一个新的实体(无不管它是什么实体),这将正常工作,因为当我插入一种进入的时间,并检查如果它已经是在数据库中,我不会有重复的问题。
everytime I add a new entity (no matter what entity it is), and this will work fine, because as I'm inserting one kind of entry at a time, and checking if it already is in the database, I won't have duplication problems.
但是,如果我想避免调用什么的SaveChanges()
这么频繁?
But what if I want to avoid calling SaveChanges()
so often?
在这个问题:的,问题的作者提供了一种方法帮助我在我的情况,但如果我添加它不起作用
的对象附加它的背景下,而不是。
In this question: Is is possible to check if an object is already attached to a data context in Entity Framework?, the author of the question provides a method that kind of helps me in my case, but it does not work if I Add
the object to the context instead of Attaching
it.
我的问题(也许两年,但非常相关的)是:是什么添加之间的差异,连接,我怎么能解决我的问题
编辑:结果
这是我遇到的问题的一个例子
Here is an example of the problem I'm having.
我有一个实体结果
的有两个实体的关系:教练
和马
。
I have an entity Result
that has a relationship with two more entities: Trainer
and Horse
.
我从外部源中的数据,所以我必须手动创建所有实体。
I get the data from an external source, so I have to create manually all the entities.
每当我需要插入一个新的教练
,我做的:
Everytime I need to insert a new Trainer
, I do:
var trainer = Trainer.CreateTrainer(Id)
然后我查询数据库,看看是否与编号
教练已经在数据库中。如果是,那么我将教练
的一个是在数据库中的变量。
Then I query the database to see if a trainer with that Id
is already on the database. If it is, then I replace the trainer
variable with the one that is on the database.
如果它不是'T,在这里我可以做两件事情:
If it isn't, I can do two things here:
- 附加教练员上下文(如果它已经存在使用该密钥,我可以检查)
- 的教练加入上下文(使用
AddToTrainers(...)
)
- Attach the trainer to the context (I can check if it already exists using the key)
- Add the trainer to the context (using
AddToTrainers(...)
)
为马
同样的过程。
现在,当我需要创建一个新的结果
(包含教练
和马
),我分配以前的教练和放大器;马这一结果实例。
Now, when I need to create a new Result
(that contains a Trainer
and a Horse
), I assign the previous trainer & horse to that result instance.
我应该怎么做在这里可以添加到背景下,新的结果
?
What should I do here to be able to add to the context that new Result
?
- 如果我附上教练/马,然后当我附上的结果,我得到
出现InvalidOperationException
,特灵我的教练已经在对象上下文。 - 如果我添加了教练,而不是安装它,我得到另一个错误(不记得了,现在,但有人告诉我,一个教练已经在数据库上)。
- If I attach the trainer/horse, then when I attach the result, I get
InvalidOperationException
, teling me that the trainer is already on the object context. - If I add the trainer instead of attaching it, I get another error (can't remember it right now, but it was telling me that a Trainer was already on the database).
重要:结果
第一个错误是安装时造成给出,做的SaveChanges()
。
我想避免在这里呼吁什么的SaveChanges()每次我添加一个新的结果。
What I want to avoid here is calling SaveChanges()
everytime I add a new result.
推荐答案
的ObjectContext
内部跟踪这是无论是背景加载,连接或添加的所有实体。只有这些实体可以在数据库时被调用的SaveChanges
进行修改。每个这样的实体有一个 ObjectStateEntry
在 ObjectStateManager
。其中的 ObjectStateEntry
的主要性能是一个国家
。国家是枚举类型 EntityState
它提供了这些值:
ObjectContext
internally tracks all entities which was either loaded by context, attached or added. Only these entities can be modified in database when SaveChanges
is invoked. Each such entity has a ObjectStateEntry
in the ObjectStateManager
. One of the main properties of the ObjectStateEntry
is a State
. The state is of enum type EntityState
which offers these values:
- 添加
- 删除
- 独立
- 修改
- 不变
- Added
- Deleted
- Detached
- Modified
- Unchanged
从数据库加载每个实体是不变
状态。独立式的特殊状态。你不会找到 ObjectStateEntry
与在 ObjectStateManager
分离的状态。但如果你问 ObjectStateManager
为 ObjectStateEntry
不通过上下文追踪实体它会创建一个新的 ObjectStateEntry
与独立
状态。
Each entity loaded from the database is in Unchanged
state. Detached is special state. You will not find ObjectStateEntry
with Detached state in the ObjectStateManager
. But if you ask ObjectStateManager
for the ObjectStateEntry
for entity not tracked by the context it will create a new ObjectStateEntry
with Detached
state.
现在的区别连接
和 ADDOBJECT
:
-
连接
- 如果调用此方法的ObjectContext
将开始跟踪整个对象图(主要实体和所有相关实体)。而尚未跟踪的所有实体将被设置为不变
状态。 -
ADDOBJECT
- 如果调用此方法的ObjectContext
也将开始跟踪整个对象图(主要实体和所有相关实体)。不同的是,这还没有被跟踪的所有实体将被设定为加状态(=必须设置到数据库中的新对象)。
Attach
- if you call this methodObjectContext
will start tracking whole object graph (main entity and all related entities). All entities which were not tracked yet will be set toUnchanged
state.AddObject
- if you call this methodObjectContext
will also start tracking whole object graph (main entity and all related entities). The difference is that all entities which were not tracked yet will be set toAdded
state (= new objects which must be set to database).
这篇关于在实体框架,就是添加和连接,我怎么能解决我的问题之间的区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!