2015-11-12 76 views
0

我不能爲我的生命找出方法(分區/ ROWNUMBER)爲什麼要做這個時查詢不運行LINQ到實體不承認

它編譯正確,但在運行時出現故障.ToList()在代碼後面顯示如下錯誤。

我已經回顧了類似的答案,但似乎每個人都具體與他們的問題。

我將查詢拆分爲多行以嘗試縮小違規代碼,並且它似乎在「//分區結束併爲每個分區生成RowCount」之後在線,但我無法弄清楚。

我借邏輯用於從這個的GroupBy /隔斷: Row_number over (Partition by xxx) in Linq?

[DataContract(Name = "Checksum")] 
public class Checksum 
{ 
    [DataMember(Name = "SortColumn")] 
    public DateTime SortColumn { get; set; } 
    [DataMember(Name = "Identifier")] 
    public string Identifier { get; set; } 
    [DataMember(Name = "Seqnum")] 
    public int Seqnum { get; set; } 
} 

public void TestLinQ() 
{ 
    myObjectContext context = new myObjectContext(); 

    DateTime startDate = new DateTime(); 

    IQueryable<Signin> iQ = context.Signin; 
     iQ = iQ.OrderBy(o => o.LastUpdateTimeStamp); 
     iQ = iQ.Where(x=>x.LastUpdateTimeStamp == startDate); 

    // Partition Over and Produce RowCount for each partition 
    IQueryable<Checksum> iQ2 = iQ.GroupBy(x => x.LastUpdateTimeStamp).Select(g => new { g, count = g.Count() }).SelectMany(t => t.g.Select(b => b).Zip(Enumerable.Range(1, t.count), (j, i) => new Checksum { SortColumn = j.LastUpdateTimeStamp, Identifier = j.SigninId, Seqnum = i })); 

    iQ2 = iQ2.Where(x => x.Seqnum < 1000); 

    // Build Checksum Code 

    List<Checksum> outlist = iQ2.ToList(); 

    // End Build Checksum Code 
} 

結果消息:

WebRole1.Tests.ContinuationTokenTests.TestLinQ拋出異常

測試方法: System.NotSupportedException :LINQ to Entities不識別方法'System.Collections.Generic.IEnumerable'1 [WebRole1.Tests.Checksum] Zip [Signin,Int32,Checksum](System.Collections.Generic.IEnumerable'1 [iSignRepo.Models.Signin ],Syste m.Collections.Generic.IEnumerable'1 [System.Int32],System.Func`3 [iSignRepo.Models.Signin,System.Int32,WebRole1.Tests.Checksum])'方法,並且此方法不能轉換爲存儲表達。

+2

它看起來像EF提供者不知道如何轉換'Zip'到SQL前執行查詢。您可能必須在該點之前從數據庫獲取數據,以便在內存中完成「Zip」操作。 – juharr

回答

0

基本上,它無法將Zip轉換爲SQL。

所有你需要做的是使用該方法

IQueryable<Checksum> iQ2 = iQ.GroupBy(x => x.LastUpdateTimeStamp) 
          .Select(g => new { g, count = g.Count() }) 
          .ToList() // Executes the Query 
          .SelectMany(t => t.g.Select(b => b).Zip(Enumerable.Range(1, t.count), (j, i) => new Checksum { SortColumn = j.LastUpdateTimeStamp, Identifier = j.SigninId, Seqnum = i })); 
+0

Yikes ....我想限制基於ZIP結果的數據集。因此,如果查詢在.ToList()時仍有150000條記錄,它是否會將其記錄到服務器,那麼代碼將使用下一個查詢部分來減少它?希望這不是太昂貴。我會試試看。謝謝!! –

+0

根據您在.Zip方法中所做的操作,您可能可以。我建議打開一個關於如何將其轉換爲EF友好代碼的新問題 – Vlad274

+0

是的,我認爲我必須這樣做,它需要一個過度的時間來運行,當直接SQL完成時,它在400ms內完成,超過100秒。 –