2014-09-29 29 views
3

我有一個奇怪的問題 - 我有一個名爲Item的表,它通過Item表中的BrandID鍵鏈接到一個名爲brand的表。單個查詢生成到實體框架中> 1100個不同的查詢

我有了導航財產在項目表遵循EF代碼第一種模式:

public virtual Brand Brand { get; set; } 

我有一個項目的名單,我送了一個名爲FilterItems方法,它從另一個得到一個謂語方法執行Where語句返回過濾圖標的列表:

public IEnumerable<Item> FilterItems(IEnumerable<Item> items) 
      { 
       string searchString = txtSearchString.Text.ToUpper(); 

       Func<Item, bool> predicate; 

       switch (Field) 
       { 
        case SearchField.Brand: 
        default: 
         predicate = BuildBrandPredicate(searchString); 
         break; 
        case SearchField.Model: 
         predicate = BuildModelPredicate(searchString); 
         break; 
        case SearchField.Note: 
         predicate = BuildNotePredicate(searchString); 
         break; 
        case SearchField.Reference: 
         predicate = BuildReferencePredicate(searchString); 
         break; 
        case SearchField.Text: 
         predicate = BuildTextPredicate(searchString); 
         break; 
       } 

       var result = items.Where(predicate); 
       return result; 
      } 

     private Func<Item, bool> BuildBrandPredicate(string searchString) 
     { 
      Func<Item, bool> predicate; 
      //build the predicate for brand 
      switch (cboSearchActions.Text) 
      { 
       case "Exact": 
        predicate = (item => item.Brand.Description.ToUpper() == searchString); 
        break; 
       //Other similar functions go here but I am concentrating on Exact 
      } 
      return predicate; 
     } 

大約有32000項和1000個品牌在每個項目的數據庫鏈接到只有一個品牌。

搜索很慢,當我調試SQL我發現它運行此程序在品牌表中的每個記錄:

Opened connection at 29/09/2014 15:14:46 +01:00 

SELECT 
    [Extent1].[ID] AS [ID], 
    [Extent1].[Description] AS [Description] 
    FROM [Brand] AS [Extent1] 
    WHERE [Extent1].[ID] = @EntityKeyValue1 


-- EntityKeyValue1: '1' (Type = Int32, IsNullable = false) 

-- Executing at 29/09/2014 15:14:46 +01:00 

-- Completed in 6 ms with result: SqlCeDataReader 

這是運行一共有1123次這是荒謬的。

當然,生成的sql應該是一個帶內連接的單個sql語句嗎?

任何人都可以解釋爲什麼這是發生以及是否有什麼我可以做些什麼來阻止這種荒謬的行爲

我使用

  1. 的Visual Studio 2012
  2. C#
  3. 的SQL Server Compact 4.0
  4. 實體框架6
  5. .Net 4.5
+0

你可以從[選擇N + 1](患上http://lostechies.com/jimmybogard/2014/04/ 03/using-automapper-to-prevent-select-n1-problems /)這裏EF的問題。 – Mrchief 2014-09-29 14:30:47

回答

5

IEnumerable<T>LINQ對象 - 你是告訴它每個項目單獨執行這些操作。除非你使用LINQ-to-some-backend,比如LINQ-to-Entities,否則它不可能組成查詢。幸運的是,這通常與IQueryable<T>更換IEnumerable<T>一樣簡單,而且Func<Foo,Bar>Expression<Func<Foo,Bar>>

public IQueryable<Item> FilterItems(IQueryable<Item> items) 
    { 
     string searchString = txtSearchString.Text.ToUpper(); 

     Expression<Func<Item, bool>> predicate; 

     switch (Field) 
     { 
      case SearchField.Brand: 
      default: 
       predicate = BuildBrandPredicate(searchString); 
       break; 
      case SearchField.Model: 
       predicate = BuildModelPredicate(searchString); 
       break; 
      case SearchField.Note: 
       predicate = BuildNotePredicate(searchString); 
       break; 
      case SearchField.Reference: 
       predicate = BuildReferencePredicate(searchString); 
       break; 
      case SearchField.Text: 
       predicate = BuildTextPredicate(searchString); 
       break; 
     } 

     var result = items.Where(predicate); 
     return result; 
    } 
    private Expression<Func<Item, bool>> BuildBrandPredicate(string searchString) 
    { 
     Expression<Func<Item, bool>> predicate; 
     //build the predicate for brand 
     switch (cboSearchActions.Text) 
     { 
      case "Exact": 
       predicate = (item => item.Brand.Description.ToUpper() == searchString); 
       break; 
      //Other similar functions go here but I am concentrating on Exact 
     } 
     return predicate; 
    } 
+0

我會+100000000000000這個如果我能!謝謝!!! – 2014-09-29 14:43:28

+0

@StevenWood做到了嗎?現在有多少個查詢? – 2014-09-29 14:44:22

+0

1查詢與Inner Join儘可能接近我自己的手動查詢。我從來沒有想過專門使用IQueryable – 2014-09-29 14:46:08