C# 实体框架 .Remove() 与 .DeleteObject()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17723626/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Entity Framework .Remove() vs. .DeleteObject()
提问by Sam Leach
You can remove an item from a database using EF by using the following two methods.
您可以使用以下两种方法使用 EF 从数据库中删除项目。
The first is on the EntityCollection
and the second on the ObjectContext
.
第一个在 上EntityCollection
,第二个在 上ObjectContext
。
When should each be used?
每个应该什么时候使用?
Is one prefered over the other?
一个比另一个更受欢迎吗?
Remove()
returns a bool
and DeleteObject()
returns void
.
Remove()
返回 abool
并DeleteObject()
返回void
。
采纳答案by Slauma
It's not generally correct that you can "remove an item from a database" with both methods. To be precise it is like so:
使用这两种方法都可以“从数据库中删除项目”通常是不正确的。准确来说是这样的:
ObjectContext.DeleteObject(entity)
marks the entity asDeleted
in the context. (It'sEntityState
isDeleted
after that.) If you callSaveChanges
afterwards EF sends a SQLDELETE
statement to the database. If no referential constraints in the database are violated the entity will be deleted, otherwise an exception is thrown.EntityCollection.Remove(childEntity)
marks the relationship between parent andchildEntity
asDeleted
. If thechildEntity
itself is deleted from the database and what exactly happens when you callSaveChanges
depends on the kind of relationship between the two:If the relationship is optional, i.e. the foreign key that refers from the child to the parent in the database allows
NULL
values, this foreign will be set to null and if you callSaveChanges
thisNULL
value for thechildEntity
will be written to the database (i.e. the relationship between the two is removed). This happens with a SQLUPDATE
statement. NoDELETE
statement occurs.If the relationship is required(the FK doesn't allow
NULL
values) and the relationship is not identifying(which means that the foreign key is not part of the child's (composite) primary key) you have to either add the child to another parent or you have to explicitly delete the child (withDeleteObject
then). If you don't do any of these a referential constraint is violated and EF will throw an exception when you callSaveChanges
- the infamous "The relationship could not be changed because one or more of the foreign-key properties is non-nullable"exception or similar.If the relationship is identifying(it's necessarily requiredthen because any part of the primary key cannot be
NULL
) EF will mark thechildEntity
asDeleted
as well. If you callSaveChanges
a SQLDELETE
statement will be sent to the database. If no other referential constraints in the database are violated the entity will be deleted, otherwise an exception is thrown.
ObjectContext.DeleteObject(entity)
将实体Deleted
标记为在上下文中。(它EntityState
是Deleted
在那之后。)如果你在SaveChanges
之后调用,EF 会向DELETE
数据库发送一条 SQL语句。如果没有违反数据库中的引用约束,实体将被删除,否则抛出异常。EntityCollection.Remove(childEntity)
标记parent 和childEntity
as之间的关系Deleted
。如果childEntity
本身从数据库中删除,调用时究竟发生了什么SaveChanges
取决于两者之间的关系类型:如果关系是可选的,即数据库中从子代到父代的外键允许
NULL
值,则此外键将设置为空,如果您调用SaveChanges
此NULL
值,childEntity
则将写入数据库(即这两个被删除)。这发生在 SQLUPDATE
语句中。没有DELETE
语句发生。如果需要该关系(FK 不允许
NULL
值)并且该关系未识别(这意味着外键不是子项(复合)主键的一部分),您必须将子项添加到另一个父项或你必须明确删除孩子(DeleteObject
然后)。如果您不执行其中任何一项操作,则会违反引用约束,EF 将在您调用时抛出异常SaveChanges
- 臭名昭著的“关系无法更改,因为一个或多个外键属性不可为空”异常或相似的。如果关系被识别(它不一定需要然后,因为主键的任何部分不能是
NULL
)EF将标记childEntity
作为Deleted
为好。如果你调用SaveChanges
一个SQLDELETE
语句就会被发送到数据库中。如果没有违反数据库中的其他引用约束,实体将被删除,否则抛出异常。
I am actually a bit confused about the Remarks section on the MSDN pageyou have linked because it says: "If the relationship has a referential integrity constraint, calling the Remove method on a dependent object marks both the relationship and the dependent object for deletion.". This seems unprecise or even wrong to me because all three cases above have a "referential integrity constraint" but only in the last case the child is in fact deleted. (Unless they mean with "dependent object" an object that participates in an identifying relationship which would be an unusual terminology though.)
实际上,我对您链接的 MSDN 页面上的备注部分感到有些困惑,因为它说:“如果关系具有参照完整性约束,则在依赖对象上调用 Remove 方法会将关系和依赖对象标记为删除。”。这对我来说似乎不准确甚至是错误的,因为上述所有三种情况都有一个“参照完整性约束”,但只有在最后一种情况下,子项实际上被删除了。(除非他们的意思是“依赖对象”是参与识别关系的对象,但这将是一个不寻常的术语。)
回答by Matas Vaitkevicius
If you really want to use Deleted, you'd have to make your foreign keys nullable, but then you'd end up with orphaned records (which is one of the main reasons you shouldn't be doing that in the first place). So just use Remove()
如果你真的想使用 Deleted,你必须让你的外键可以为空,但是你最终会得到孤立的记录(这是你首先不应该这样做的主要原因之一)。所以只需使用Remove()
ObjectContext.DeleteObject(entity)marks the entity as Deleted in the context. (It's EntityState is Deleted after that.) If you call SaveChanges afterwards EF sends a SQL DELETE statement to the database. If no referential constraints in the database are violated the entity will be deleted, otherwise an exception is thrown.
ObjectContext.DeleteObject(entity)在上下文中将实体标记为已删除。(之后 EntityState 被删除。)如果您在之后调用 SaveChanges,EF 会向数据库发送 SQL DELETE 语句。如果没有违反数据库中的引用约束,实体将被删除,否则抛出异常。
EntityCollection.Remove(childEntity)marks the relationship between parent and childEntity as Deleted. If the childEntity itself is deleted from the database and what exactly happens when you call SaveChanges depends on the kind of relationship between the two:
EntityCollection.Remove(childEntity)将 parent 和 childEntity 之间的关系标记为 Deleted。如果 childEntity 本身从数据库中删除,那么调用 SaveChanges 时究竟发生了什么取决于两者之间的关系类型:
A thing worth noting is that setting .State = EntityState.Deleted
does not trigger automatically detected change.(archive)
值得注意的是,设置.State = EntityState.Deleted
不会触发自动检测到的更改。(存档)