簡體   English   中英

C#LINQ查詢(MYSQL EF) - 獨特和最新記錄

[英]C# LINQ query (MYSQL EF) - Distinct and Latest Records

我有一張桌子,我們稱之為Record。 包含:ID(int)| CustID(int)| 時間(日期時間)| 數據(varchar)

我需要每位客戶的最新(最新)記錄:

SQL

select * from record as i group by i.custid having max(id);

LINQ版本1

dgvLatestDistinctRec.DataSource = from g in ee.Records
                                  group g by g.CustID into grp
                                  select grp.LastOrDefault();

這會引發錯誤:

System.NotSupportedException未被用戶代碼處理Message = LINQ to Entities無法識別方法'Faizan_Kazi_Utils.Record LastOrDefault [Record](System.Collections.Generic.IEnumerable`1 [Faizan_Kazi_Utils.Record])'方法,而且此方法不能翻譯成商店表達。 來源= System.Data.Entity的

LINQ版本2

var list = (from g in ee.Records
            group g by g.CustID into grp
            select grp).ToList();
Record[] list2 = (from grp in list
                  select grp.LastOrDefault()).ToArray();
dgvLatestDistinctRec.DataSource = list2;

這是有效的,但效率很低,因為它將數據庫中的所有記錄加載到內存中,然后只提取每個組的最后一個(最近的成員)。

是否有任何LINQ解決方案可以提高上述SQL解決方案的效率和可讀性?

更新:

var results = (from rec in Record group rec by rec.CustID into grp 
    select new
    {
        CustID = grp.Key,
        ID = grp.OrderByDescending(r => r.ID).Select(x => x.ID).FirstOrDefault(),
        Data = grp.OrderByDescending(r => r.ID).Select(x => x.Data).FirstOrDefault()
    }
);

所以我制作了一個測試表並編寫了一個Linq - > SQL Query,它將完全滿足您的需求。 看看這個,讓我知道你的想法。 如果這個查詢被縮放,唯一要記住的是我相信它會在select new中分組后為每個CustID記錄運行一個查詢。 唯一可以確定的方法是在運行查詢信息時運行SQL Tracer .. http://www.foliotek.com/devblog/tuning-sql-server-for-programmers/

原版的:

你能做這樣的事嗎? from g in ee.Records where g.CustID == (from x in ee.Records where (g.CustID == x.CustID) && (g.ID == x.Max(ID)).Select(r => r.CustID))

這都是偽代碼,但希望你能得到這個想法。

我可能來不及幫助解決您的問題,但我遇到了類似的問題,並且能夠通過以下查詢獲得所需的結果:

from g in ee.Records
group g by g.CustID into grp
from last in (from custRec in grp where custRec.Id == grp.Max(cr => cr.Id) select custRec)
select last

我認為grp.LastOrDefault()是一個C#函數,是SQL不知道的。 LINQ將您的查詢轉換為SQL查詢,以便您的數據庫服務器了解。 您可能希望嘗試創建存儲過程,或者以其他方式過濾掉您要查找的內容。

第二個查詢工作的原因是因為LINQ to SQL返回一個列表,然后在C#列表上執行LINQ查詢(以過濾掉你需要的內容),它實現了IEnumerable / IQueryable接口並理解了grp.LastOrDefault() 。

如果用簡單的Last()替換LastOrDefault()怎么辦? (是的,你必須檢查你的記錄表是不是空的)

因為我無法看到MySQL如何返回“默認”組的方式。 這不是可以簡單地轉換為SQL的東西。

我有另一個想法:

// Get a list of all the id's i need by:
// grouping by CustID, and then selecting Max ID from each group.
var distinctLatest = (from x in ee.Records
                          group x by x.CustID into grp 
                          select grp.Max(g => g.id)).ToArray();

// List<Record> result = new List<Record>();

//now we can retrieve individual records using the ID's retrieved above
// foreach (int i in distinctLatest)
// {
//    var res = from g in ee.Records where g.id == i select g;
//    var arr = res.ToArray();
//    result.Add(res.First());
// }

// alternate version of foreach
dgvLatestDistinctRec.DataSource = from g in ee.Records
                                           join i in distinctLatest
                                           on g.id equals i
                                           select g;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM