2012-05-02 93 views
4

所以我有一個非常簡單的結構:與實體框架一個簡單的查詢性能很差

  • 我有有一個獨特的訂單號碼訂單
  • 訂單有很多OrderRows
  • OrderRows有很多RowExtras那有2個字段,位置(OrderRow內的RowExtra的序列號)和Info,它是一個字符串。多數情況下,OrderRow沒有多個RowExtra。

(不介意傻結構現在,它只是它是如何)。

所以現在我得到的對象,具有以下三個屬性的列表:

  • ORDERNUMBER
  • 位置
  • 信息

我想要做的只是爲1)檢查具有給定OrderNumber/Position -pair的RowExtra存在於數據庫中,如果是,則2)更新Info-property。

我已經嘗試了幾種不同的方法來完成這一點,最好的結果非常糟糕。該解決方案遍歷對象的列表,並出具查詢如

myContext.RowExtras.Where(x => x.Position == currentPosition && 
          x.OrderRow.Order.OrderNumber == currentOrderNumber) 

或從另一個側面去

myContext.Orders.Where(x => x.OrderNumber == currentOrderNumber) 
       .SelectMany(x => x.OrderRows) 
       .SelectMany(x => x.RowExtras) 
       .Where(x => x.Position == currentPosition) 

,然後檢查是否計數等於1,如果是,更新屬性,否則繼續下一個項目。

我目前在數據庫中大約有4000個RowExtras,需要更新大約一半。這些方法使程序需要幾分鐘才能完成,這是不可接受的。我不明白的是爲什麼需要這麼長時間,因爲返回所需RowExtra的SQL子句將非常易於手動編寫(在where-part中只有2個連接和2個條件)。

我管理,以達到最佳性能與compiledquery看起來像這樣

Func<MyContext, int, string, IQueryable<RowExtra>> query = 
CompiledQuery.Compile( 
    (MyContext ctx, int position, string orderNumber) => 
    from extra in ctx.RowExtras 
    where 
     extra.Position == position && 
     extra.OrderRow.Order == orderNumber 
    select extra); 

,然後調用說在我的列表中的每個對象查詢。但即使這種方法也花了一分鐘。那麼我怎麼才能讓這件事情在合理的時間內運行呢?

另外,我很抱歉太長的解釋,但希望有人能幫助我!

+2

查詢本身可能不是問題 - 事實上,你做了2000個單獨的更新很可能是。 – BrokenGlass

+0

您可能可以對數據庫進行更通用的請求,然後處理內存?我的邏輯越少,我可以更好地回溯數據庫。 – Brendan

+0

嗯好吧,它也發生,可能大約一半的更新是沒有必要的,這意味着新的信息與保存在數據庫中的信息相同。如果我添加了一張支票,並且只更新了屬性(如果它與舊的不同),還是EF會自動處理這種東西,會有幫助嗎? – bobblez

回答

1

儘量減少數據庫調用次數。作爲一個經驗法則,每個人至少需要大約10ms - 即使只返回一個標量。

因此,一般來說,一次性提取所有需要的數據,在代碼中對其進行修改並保存。

List<Order> orders = myContext.Orders 
    .Include("OrderRows.RowExtras") 
    .Where(... select all the orders you want, not just one at a time ...) 
    .ToList(); 

foreach (Order order in orders) 
{ 
    ... execute your logic on the in-memory model 
} 

myContext.SaveChanges();