SQL linq伪代码查询

SQL query in linq pseudocode

我只需要输出 table 中的最后一条记录,但只输出组中的那些用户。我只能显示组中的那些人。但我无法获得最后的记录。 我写了2个请求,第一个报错,第二个输出所有记录...

foreach (var item1 in brigades.Persons)
            {
                var persontrack =
                from s in new DataContext().GetTable<PersonTrack>()
                join t in a on s.PersonId equals t.Id
                where t.Id == item1.Id
                group s by s.Id into grp
                from last in (from custRec in grp where custRec.Id == grp.Max(cr => cr.Id) select custRec)
                select last;
                ps.AddRange(persontrack);
            }

foreach (var item in brigades.Persons)
        {
            var persontrack = from s in new DataContext().GetTable<PersonTrack>()
                              join t in brigades.Persons on s.PersonId equals t.Id
                              where t.Id == item.Id
                              orderby s.Id
                              descending
                              select s;
            ps.AddRange(persontrack);
        }

据我所知,这只有用 C# 编写 linq 的方式才有可能。

快速修复

如果您添加 FirstOrDefault,您的第二个查询将会成功(查询得到 translated 到 sql,即使这样写,并且只有最后一个元素返回)。

using (var db = new DataContext())    // create once to gain performance
{
    foreach (var item in brigades.Persons)
    {
        var persontrack = (from s in db.GetTable<PersonTrack>()
                           join t in brigades.Persons on s.PersonId equals t.Id
                           where t.Id == item.Id
                           orderby s.Id
                           descending
                           select s).FirstOrDefault();
        if (persontrack != null)
            ps.Add(persontrack);
    }
}   // DataContext is disposed here

或者这也可以,但是添加空值会很奇怪:

ps.Add(persontrack.FirstOrDefault());

备选

但是,使用 foreach 会导致多次调用 db。您可以将其重写为单个查询,如下所示:

using (var db = new DataContext())
{
    var eachLastTrack = from s in db.GetTable<PersonTrack>()
                        join t in brigades.Persons on s.PersonId equals t.Id
                        // group by PersonId instead, to avoid foreach!
                        group s by s.PersonId into grp 
                        select grp.OrderByDescending(s => s.Id).FirstOrDefault();
                        // note: FirstOrDefault() applied for each "t.Id"!
    ps.AddRange(eachLastTrack);
}