2011-03-18 103 views
2

我想爲我的模型/數據訪問使用實體框架,並運行速度問題,希望有人可以協助?實體框架 - 對象屬性

我一直在做的是使用EF圖和默認的代碼生成器來生成部分類,描述將要持久化的任何東西。然後我有方法和非持久屬性的部分類。這些可能是簡單的事情,例如全名作爲連接的姓/名,或者從相關實體派生,例如總庫存作爲庫存位置數量集合的總和。

訪問相關實體的任何方法都可以工作,但似乎很慢。這裏有一個特別的慢中的一個例子,它需要大約6-7秒:參與實體

簡單描述:

供應商 - >提供了許多SupplierLines,每個人都有成本價 SupplierLine - >細分StockLine StockLine - >有很多地點,每個地點都有數量

所以我想添加一個方法來從供應商那裏獲得總庫存價值,即mySupplier.StockValue()這顯然應該是總數的成本價格×每個供應商行及其股票行的總量。

我在供應商完成這是一個功能:

Public Function StockValue() As Decimal 
     Return SupplierLines. 
      Sum(Function(sul) sul.LastPrice * sul.StockLines.Sum(Function(skl) skl.Locations.Sum(Function(l) l.Quantity))) 
    End Function 

其中給出正確的結果,但需要永遠這樣做。

有關如何獲得更好結果的任何想法?

  • 我要保持我的模型類持久性的無知
  • 我希望把我所有的邏輯編譯檢查
  • 我想一切使用假數據源
  • 我是輕鬆的單位可測試並不是真的要預先加載這些信息,因爲它並不總是需要的
+0

您是否嘗試使用探查器來查看SQL服務器上正在執行的查詢實體框架? – 2011-03-18 18:19:57

回答

1

我發現了一個包括()...擴展IEnumerable的方法,並使用它。它解決了性能問題,同時保持對上下文的無知。

1

你的問題是最有可能的延遲加載。如果只加載Supplier實體,則它不會加載其實際的SupplierLine實例,它們與StockLine實例及其相關的Location實例相關。如果這是真的情況下,情況如下(如果你在查詢檢索Supplier沒有Include他們):

  1. SupplierLines. - 執行查詢數據庫來獲取所有線路的電流供應商
  2. sul.StockLines. - 單獨執行查詢每個供給線的,以獲取其股票行
  3. skl.Locations. - 爲每個股份行執行單獨的查詢來獲取其位置

因此,根據您在這些集合中擁有的數據量,您最終可能會在第一次撥打StockValue時執行數十到數千次sql查詢。下一次呼叫將會很快,因爲數據已經被加載。

如果你想避免它,你必須與所有realted數據檢索供應商:

context.Supplier.Include("SupplierLines.StockLines.Locations").Where(...); 
+0

我擔心的是......供應商的方法現在取決於上下文......以及硬編碼字符串 – RichardW1001 2011-03-18 19:22:10

+0

供應商不依賴上下文(不直接)。上面的代碼應該代表在上下文實例中公開的對象集(不是直接供應商)。如果您想重構導航屬性的名稱,則硬編碼字符串可能會出現問題。有強烈類型的選擇,但您必須使用EF 4.1 RC。 – 2011-03-18 19:34:27

+0

嗯,你是說從上下文(即控制器)獲取供應商的東西應該包含?我想這幾乎是公平的,因爲控制器依賴於上下文,並且知道它想訪問該屬性。雖然感覺凌亂。我正在使用存儲庫模式來訪問我的數據,所以假設這也意味着我需要公開Include方法或類似方法。 – RichardW1001 2011-03-18 20:58:58