2012-08-12 67 views
2

我有以下功能(在WCF服務託管,如果該事項):四處逛逛缺乏「包含」在LINQ到實體

public List<IceVsRepositoryFile> GetRepositoryFilesByRepositoryId(int repId) 
    { 
     var entity = new IceVSEntities(); 
     var files = from p in entity.Files where p.RepositoryId == repId select p.FileId; 
     List<long> iList = files.ToList(); 
     var repFiles = from p in entity.RepositoryFiles where iList.Contains(p.FileId) select p; 

     if (!repFiles.Any()) 
      return null; 

     var retFiles = repFiles.ToList().Select(z => new IceVsRepositoryFile 
      { 
       FileId = (int)z.FileId, 
       RollbackFileId = (int)z.RollbackFileId, 
       UserId = (int)z.UserId, 
       FileContents = z.FileContents, 
       ChangeDescription = z.ChangeDescription 
      }).ToList(); 

     return retFiles; 
    } 

當我運行這個功能我正在以下一個錯誤,說「LINQ to Entities不能識別該方法'布爾包含(Int64)'方法,並且這種方法不能被翻譯成一個存儲表達式

我明白爲什麼我會收到錯誤信息。我如何重寫我的查詢,使其按預期工作?我的後端數據庫,如果它很重要,如果SqlLite 3.我正在使用.NET 3.5。

回答

1

您使用的包含爲List,它不在IEnumerable中,因此無法轉換爲相應的SQL查詢。相反,你可以使用Any,...這樣的:

iList.Any(x=>x == p.FileId) (or use related property) 

而且與其做:

List<long> iList = files.ToList(); 

使用files.Any...在查詢中,從太多的從數據庫獲取防範。實際上使用IEnumerable函數而不是List函數。

+0

我覺得這個問題實際上是一個數據庫沒有ILIST或文件,因此它無法過濾基於他們。我不認爲改變對「任何」的呼籲將有所幫助。如果RepositoryFiles足夠小以至於它不會加載到內存中,那麼我會在它上面調用ToList()。另一個選擇是將兩個查詢合併爲一個,但這可能會重複ReposityryFiles中每個項目的第一個查詢。第一個查詢上的ToList()也會停止此查詢多次觸擊數據庫。 – TheEvilPenguin 2012-08-12 23:14:51

+0

@ TheEvilPenguin,我的回答是絕對正確的,它不值得讚揚,downvote是錯誤的答案。你所有的猜測都是錯誤的。由於延期執行,代碼的執行將會推遲(按照我寫的方式),但是你的建議似乎是正確的,不需要比思維更好。 – 2012-08-12 23:46:44

+0

您的回答並沒有解決將LINQ轉換爲SQL的問題,並且您提供了一些不合格的建議,但沒有任何資格或解釋。 .ToList()是有原因的,並且會在這種情況下有所幫助。它不應該無意識地避免。 .Any()很好理解,但在這裏毫無意義。然而,我並沒有讓你失望。雖然是邊界線。 – TheEvilPenguin 2012-08-13 00:30:19

0

你在Files和RepositoryFiles之間有關係嗎?如果是這樣,這樣做會更容易做到這一點:

var repFiles = from p in entity.RepositoryFiles where p.File.RepositoryId == repId select p; 

這將避免無法將查詢轉換爲SQL的問題。

+0

我沒有任何關係。雖然這將是一個簡單的解決方案 – Icemanind 2012-08-12 23:47:38

1

我相信加入可以這樣做:

public List<IceVsRepositoryFile> GetRepositoryFilesByRepositoryId(int repId) 
{ 
    var entity = new IceVSEntities();  

    var repFiles = from file in entity.Files where file.RepositoryId == repId join repFile in entity.RepositoryFiles on repFile.FileId equals file.FileId select repFile; 

    var retFiles = // as before 

    return retFiles; 

}