我正在使用WPF,实体框架和SQLServer编写一个应用程序,所有这些都是非常重要的。我正在查看使用sql profiler对数据库进行的调用,并发现了一些不必要的调用。第一个问题很容易解决,但我已经将它包含在将来阅读此主题的任何人中。假设我有一个包含3个表的表结构,例如Invoice-> InvoiceDetail-> Product
1)当我加载一个Invoice对象时,它将执行一个单独的语句来检索每个InvoiceDetail项。使用Include语句可以很容易地解决这个问题,例如
context.Invoices.Include("InvoiceDetails").Where(i => i.Something == somethingelse);
2)当我删除Invoice时,数据库有一个级联删除,它会自动删除所有InvoiceDetails。但是,EF仍然坚持为内存中的每个InvoiceDetail对象调用一个删除操作。如果发票上有100个项目,那么它将执行101个语句而不是1.这很糟糕。
3)除了在第2点执行的额外声明之外,假设每个InvoiceDetail对象指向一个产品并且我已经将产品加载到内存中(如果我在删除之前显示发票,则会发生这种情况)然后EF对每个产品执行无用的更新语句!!!!事实上,这个更新声明是无用的,因为如果其他人同时改变了产品的某些内容,那么这段代码将改变数据!如果我正在记录更改,那么我们会得到无用的日志条目。我怀疑它是这样做的,因为Product会有一个InvoiceDetails集合,它已删除了一些项目,但产品本身没有改变,为什么要更新?
感谢阅读 干杯, 迈克尔
答案 0 :(得分:2)
Product
中的更改,则必须参与optimistic concurrency。在这种情况下,您的更改不会被覆盖,但删除操作会因OptimisticConcurrencyException
而失败。我将在稍后检查此行为,并告诉您我是否能够重现它并找到任何解决方法。答案 1 :(得分:0)
要删除级联删除(并且可能依赖SQL Server进行删除),请参阅此处的方法:http://geekswithblogs.net/danemorgridge/archive/2010/12/17/ef4-cpt5-code-first-remove-cascading-deletes.aspx
答案 2 :(得分:0)
我一直在使用它作为一种解决方案,让SQL Server在没有EF命中的情况下处理级联删除。
Public Sub DeleteCheckedOutByUser(ByVal username As String)
Dim cmd As String = String.Format("delete Maintenance.CheckoutManager where CheckOutTo = '{0}'", username)
_context.ExecuteStoreCommand(cmd)
End Sub
很抱歉,这是在VB中,这是我当前的客户端正在使用的。如果您在翻译我所说的内容时遇到任何问题,请告诉我。