如何从entity framework模型中删除一个对象,而无需先加载它?
我确定我已经在某个地方看到了这个问题的答案,但是因为我在SO或者谷歌上search了几个search词,所以无论如何我都会问这个问题。
在entity framework中,删除数据对象的唯一方法似乎是
MyEntityModel ent = new MyEntityModel(); ent.DeleteObject(theObjectToDelete); ent.SaveChanges();
但是,这种方法要求首先将对象加载到控制器中,只是将其删除。 有没有办法删除仅引用其实例ID的业务对象?
如果使用Linq或Lambdaexpression式更聪明,那也可以。 但是,主要目标是避免加载数据只是为了删除它。
值得一提的是Entity Framework同时支持Linq to Entities和Entity SQL。 如果您发现自己想要执行可能会影响许多logging的删除或更新,则可以使用ExecuteNonQuery
的等效项。
在实体SQL中,这可能看起来像
Using db As New HelloEfEntities Dim qStr = "Delete " & _ "FROM Employee" db.ExecuteStoreCommand(qStr) db.SaveChanges() End Using
在这个例子中, db
是我的ObjectContext
。 另请注意, ExecuteStoreCommand
函数采用可选的参数数组。
我发现这个post ,其中指出,真的没有更好的方式来删除logging。 给出的解释是这个logging唯一的所有外键,关系等也被删除,所以EF需要有正确的logging信息。 如果不加载数据,为什么不能实现这一点,我感到困惑,但是由于不会经常发生,所以我决定(现在)我不打扰。
如果你有这个问题的解决scheme,请随时让我知道=)
提前道歉,但我不得不质疑你的目标。
如果删除了一个对象而没有读取它,那么在确认要删除该对象的时间与实际的删除时间之间,您无法知道另一个用户是否已经更改了该对象。 在“普通的旧SQL”中,这就像是在做:
DELETE FROM FOO WHERE ID = 1234
当然,大多数人并没有这样做。 相反,他们做的是这样的:
DELETE FROM FOO WHERE ID = 1234 AND NAME = ?ExpectedName AND...
重点是,如果其他用户在过渡期间更改了logging,则删除应该失败(不执行任何操作)。
有了这个,更好地说明问题,使用entity framework有两种可能的解决scheme。
-
在你的Delete方法中,现有的实例比较属性的期望值,如果它们相同则删除。 在这种情况下,entity framework将负责编写一个包含属性值的DELETE语句。
-
编写一个同时接受IDE和其他属性值的存储过程,并执行该过程。
有一种方法可以通过重新计算EntityKey来加载实体。 它看起来像一个黑客,但可能是在EF做到这一点的唯一方法。
博客文章删除不提取
你可以创build一个具有相同ID的对象,并将其传递给删除,但如果你有复杂的关系,你可能需要更多的
var user = new User { ID = 15 }; context.Entry(user).State = EntityState.Deleted; context.SaveChanges();
var toDelete = new MyEntityModel{ GUID = guid, //or ID = id, depending on the key }; Db.MyEntityModels.Attach(toDelete); Db.MyEntityModels.DeleteObject(toDelete); Db.SaveChanges();
如果你的密钥包含多个列,你需要提供所有的值(例如GUID,columnX,columnY等)。
如果你觉得有些奇特,那么也可以看看这里的generics函数。
entity framework5有entity framework扩展库 。 在NuGet上可用。 那么你可以写下如下的东西:
context.Users.Delete(u => u.Id == id);
这对批量删除也很有用。