2013-07-22 59 views
1

當我執行下面的代碼時,我得到這個錯誤,任何想法如何解決它?LINQ to Entities不能識別方法'Int32 Min(Int32,Int32)'?


LINQ to Entities does not recognize the method 'Int32 Min(Int32, Int32)' method, and this method cannot be translated into a store expression. 

result = items.ToList() 
        .Select(b => new BatchToWorkOnModel() 
        { 
         BatchID = b.Batch.ID, 
         SummaryNotes = b.Batch.Notes, 
         RowVersion = b.Batch.RowVersion, 
         Items = items 
          .Select(i => new ItemToWorkOnModel() 
          { 
           SupplierTitle = i.Title, 
           ItemID = i.ID, 
           BatchID = i.BatchID ?? 0, 
           ItemDate = i.PubDate, 
           // KB - Issue 276 - Return the correct Outlet name for each item 
           Outlet = i.Items_SupplierFields != null ? i.Items_SupplierFields.SupplierMediaChannel != null ? i.Items_SupplierFields.SupplierMediaChannel.Name : null : null, 
           Status = ((short)ItemStatus.Complete == i.StatusID ? "Done" : "Not done"), 
           NumberInBatch = i.NumInBatch, 
           Text = string.IsNullOrEmpty(i.Body) ? "" : i.Body.Substring(0, Math.Min(i.Body.Length, 50)) + (i.Body.Length < 50 ? "" : "..."), 
           IsRelevant = i.IsRelevant == 1, 
           PreviouslyCompleted = i.PreviouslyCompleted > 0 ? true : false 
          }).ToList() 
        }) 
        .FirstOrDefault(); 

回答

2

看來Math.Min不是由EF查詢提供實現。您應該可以通過簡單地將AsEnumerable應用於您的項目集合來修復它,以使用Linq to Objects來執行表達式;

Items = items.AsEnumerable().Select(i => new ItemToWorkOnModel()... 

如果添加where條件的項目選擇(似乎有點陌生,採取在整個表中的所有項目),你會想AsEnumerable()之前將其添加到允許EF做濾波在數據庫中。

另外,您只需要查詢的第一個結果,但是在將列表切割爲單個項目之前,您正在使用ToList()獲取所有。您可能想要刪除ToList(),以便EF /基礎數據庫只能返回單個結果;

result = items.Select(b => new BatchToWorkOnModel()... 
+1

我原則上同意你的意見。然而再來看看源代碼。鑑於'.ToList()'的數量,我們應該運行LinqToObject而不是LinqToEF。我不確定源代碼是否正確... – Aron

+0

@Aron主查詢中的第一個ToList()不會影響子查詢(它基本上只是將整個表讀入一個List),並且子查詢包含ToList()_after_所有選擇都已完成,因此它將使用Linq to Entities進行查詢/投影。 –

+0

我注意到子屬性可能不會被加載,因此會產生n + 1個查詢。不過,我認爲(取決於實施)該屬性可能實現爲一個List <>。這表明子列表是通過Lazy Loading獲取的,而不是顯式的EF查詢。同樣,結果是List上的投影,而不是DbSet/DbQuery/ObjectSet/ObjectQuery。 – Aron

1

您不需要Math.Min

有問題的行是:

Text = string.IsNullOrEmpty(i.Body) 
     ? "" : i.Body.Substring(0, Math.Min(i.Body.Length, 50)) + (i.Body.Length < 50 ? "" : "...") 

那麼這行的回報?

如果i.Body爲空或空它將返回一個空字符串。如果長度爲50個或更多字符,則返回50個字符的子字符串並附加「...」。
如果長度小於50,它將接收一個帶有字符串長度的子字符串並附加一個空字符串。但這只是原始字符串。

Text = string.IsNullOrEmpty(i.Body) 
     ? "" : (i.Body.Length < 50 ? i.Body : i.Body.Substring(0, 50) + "...") 
相關問題