C#LINQ查询(MYSQL EF) - 独特和最新记录

时间:2011-08-29 20:34:28

标签: c# mysql linq entity-framework-4 distinct

我有一张桌子,我们称之为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 [实录   ](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解决方案的效率和可读性?

5 个答案:

答案 0 :(得分:4)

更新

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))

这都是伪代码,但希望你能得到这个想法。

答案 1 :(得分:2)

我可能来不及帮助解决您的问题,但我遇到了类似的问题,并且可以通过以下查询获得所需的结果:

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

答案 2 :(得分:1)

我认为grp.LastOrDefault()是一个C#函数,是SQL不知道的。 LINQ将您的查询转换为SQL查询,以便您的数据库服务器了解。您可能希望尝试创建存储过程,或者以其他方式过滤掉您要查找的内容。

第二个查询的工作原因是因为LINQ to SQL返回一个列表,然后在C#列表上执行LINQ查询(以过滤掉你需要的内容),它实现了IEnumerable / IQueryable接口并理解了grp。 LastOrDefault()。

答案 3 :(得分:1)

如果用简单的Last()替换LastOrDefault()怎么办? (是的,你必须检查你的记录表是不是空的)

因为我无法看到MySQL如何返回“默认”组。这不是可以简单地转换为SQL的东西。

答案 4 :(得分:0)

我有另一个想法:

// 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;