asp.net-mvc 如何在不首先加载对象的情况下从实体框架模型中删除对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/502795/
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
How do I delete an object from an Entity Framework model without first loading it?
提问by Tomas Aschan
I am quite sure I've seen the answer to this question somewhere, but as I couldn't find it with a couple of searches on SO or google, I ask it again anyway...
我很确定我已经在某处看到了这个问题的答案,但是由于我在 SO 或 google 上进行了几次搜索都找不到它,所以我还是再问一遍......
In Entity Framework, the only way to delete a data object seems to be
在实体框架中,删除数据对象的唯一方法似乎是
MyEntityModel ent = new MyEntityModel();
ent.DeleteObject(theObjectToDelete);
ent.SaveChanges();
However, this approach requires the object to be loaded to, in this case, the Controller first, just to delete it. Is there a way to delete a business object referencing only for instance its ID?
但是,这种方法需要先将对象加载到控制器,在这种情况下,首先将其删除。有没有办法删除仅引用其 ID 的业务对象?
If there is a smarter way using Linq or Lambda expressions, that is fine too. The main objective, though, is to avoid loading data just to delete it.
如果有使用 Linq 或 Lambda 表达式的更聪明的方法,那也很好。但是,主要目标是避免加载数据只是为了删除它。
采纳答案by John Wigger
It is worth knowing that the Entity Framework supports both to Linq to Entities and Entity SQL. If you find yourself wanting to do deletes or updates that could potentially affect many records you can use the equivalent of ExecuteNonQuery.
值得知道的是,实体框架同时支持 Linq to Entities 和实体 SQL。如果您发现自己想要进行可能影响许多记录的删除或更新,您可以使用ExecuteNonQuery.
In Entity SQL this might look like
在实体 SQL 中,这可能看起来像
Using db As New HelloEfEntities
Dim qStr = "Delete " & _
"FROM Employee"
db.ExecuteStoreCommand(qStr)
db.SaveChanges()
End Using
In this example, dbis my ObjectContext. Also note that the ExecuteStoreCommandfunction takes an optional array of parameters.
在这个例子中,db是我的ObjectContext. 另请注意,该ExecuteStoreCommand函数采用可选的参数数组。
回答by Tomas Aschan
I found this post, which states that there really is no better way to delete records. The explanation given was that all the foreign keys, relations etc that are unique for this record are also deleted, and so EF needs to have the correct information about the record. I am puzzled by why this couldn't be achieved without loading data back and forth, but as it's not going to happen very often I have decided (for now) that I won't bother.
我找到了这篇文章,它指出确实没有更好的方法来删除记录。给出的解释是该记录唯一的所有外键、关系等也被删除,因此 EF 需要有关于该记录的正确信息。我很困惑为什么不来回加载数据就无法实现这一点,但由于它不会经常发生,我决定(现在)我不会打扰。
If you do have a solution to this problem, feel free to let me know =)
如果您确实有解决此问题的方法,请随时告诉我 =)
回答by Craig Stuntz
Apologies in advance, but I have to question your goal.
提前道歉,但我不得不质疑你的目标。
If you delete an object without ever reading it, then you can't know if another user has changed the object in between the time you confirmed that you wanted to delete the object and the actual delete. In "plain old SQL", this would be like doing:
如果您在没有读取对象的情况下删除它,那么您无法知道在您确认要删除对象和实际删除之间是否有其他用户更改了该对象。在“普通的旧 SQL”中,这就像做:
DELETE FROM FOO
WHERE ID = 1234
Of course, most people don't actually do this. Instead, they do something like:
当然,大多数人实际上并没有这样做。相反,他们执行以下操作:
DELETE FROM FOO
WHERE ID = 1234
AND NAME = ?ExpectedName AND...
The point is that the delete should fail (do nothing) if another user has changed the record in the interim.
关键是如果另一个用户在此期间更改了记录,则删除应该失败(什么都不做)。
With this, better statement of the problem, there are two possible solutions when using the Entity Framework.
有了这个,更好地说明问题,使用实体框架时有两种可能的解决方案。
In your Delete method, the existing instance, compare the expected values of the properties, and delete if they are the same. In this case, the Entity Framework will take care of writing a DELETE statement which includes the property values.
Write a stored procedure which accepts both the IDE and the other property values, and execute that.
在您的 Delete 方法中,现有实例比较属性的预期值,如果相同则删除。在这种情况下,实体框架将负责编写包含属性值的 DELETE 语句。
编写一个接受 IDE 和其他属性值的存储过程,然后执行它。
回答by biozinc
There's a way to spoof load an entity by re-calculating it's EntityKey. It looks like a bit of a hack, but might be the only way to do this in EF.
有一种方法可以通过重新计算实体的 EntityKey 来欺骗加载实体。它看起来有点像黑客,但可能是在 EF 中做到这一点的唯一方法。
Blog article on Deleting without Fetching
关于删除而不获取的博客文章
回答by CMS
You can create an object with the same id and pass it through to the delete BUT its good for simple objects if you have complex relations you may need more than that
您可以创建一个具有相同 id 的对象并将其传递给删除,但如果您有复杂的关系,它对简单对象有好处,您可能需要更多
var user = new User { ID = 15 };
context.Entry(user).State = EntityState.Deleted;
context.SaveChanges();
回答by tymtam
var toDelete = new MyEntityModel{
GUID = guid,
//or ID = id, depending on the key
};
Db.MyEntityModels.Attach(toDelete);
Db.MyEntityModels.DeleteObject(toDelete);
Db.SaveChanges();
In case your key contains multiple columns, you need to provide all values (e.g. GUID, columnX, columnY etc).
如果您的键包含多个列,您需要提供所有值(例如 GUID、columnX、columnY 等)。
Have also a look herefor a generic function if you feel for something fancy.
如果你觉得有什么花哨的东西,也可以看看这里的通用函数。
回答by acarlon
With Entity Framework 5 there is Entity Framework Extended Library. Available on NuGet. Then you can write something like:
实体框架 5 有实体框架扩展库。在 NuGet 上可用。然后你可以写一些类似的东西:
context.Users.Delete(u => u.Id == id);
It is also useful for bulk deletes.
它也可用于批量删除。

