选择整行时LINQ to pngSQL问题

时间:2013-07-03 19:13:31

标签: sql linq

我有一个简单的查询:选择parentId不为null的最新行。我已经在LINQ(lambda)和SQL中制定了查询。我试图找回最近的孩子。我将尝试可视化我需要的数据。

原始数据:

-------------------------------
- Id - ParentId - CreatedDate -
-------------------------------
-  1 -          -  07/01/2013 -
-  2 -          -  07/01/2013 -
-  3 -          -  07/01/2013 -
-  4 -        1 -  07/02/2013 -
-  5 -        2 -  07/03/2013 -
-  6 -        2 -  07/04/2013 -
-  7 -        1 -  07/05/2013 -
-------------------------------

查询返回的数据

-------------------------------
- Id - ParentId - CreatedDate -
-------------------------------
-  6 -        2 -  07/04/2013 -
-  7 -        1 -  07/05/2013 -
-------------------------------

以下是我目前正在尝试的内容:

SQL:

SELECT a."ParentId", MAX(a."CreatedDate")
FROM "myTable" AS a
WHERE a."ParentId" IS NOT NULL
GROUP BY a."ParentId"

LINQ(拉姆达):

var uniqueChildren = myTable.Where(a => a.ParentId != null)
        .GroupBy(a => a.ParentId)
        .Select(b => new { ParentId = b.Key, CreatedDate = b.Max(t => t.CreatedDate) });

这会返回几行,包括键(ParentId)和创建日期。我想为此返回整行而不是两条信息。我搜索了类似的问题并找到了可能的解决方案:

var q = from n in table
        group n by n.ParentId into g
        select g.OrderByDescending(t=>t.CreatedDate).First();

这看起来很有前景,所以我在PostgreSQL数据库上运行它并从VisualStudio收到以下错误:

"The method 'First' can only be used as a final query operation. Consider using the method 'FirstOrDefault' in this instance instead."

好的消息非常简单,让我试试这样:

var q = from n in table
        group n by n.ParentId into g
        select g.OrderByDescending(t=>t.CreatedDate).FirstOrDefault();

现在我又收到了一个错误:

The method or operation is not implemented

我似乎无法在这里休息一下。我继续使用我知道不会导致任何问题的命令将一个草率的解决方案整合在一起:

var q2 =
    (from a in myTable
     join b in
         (myTable.Where(a => a.ParentId != null)
                 .GroupBy(a => a.ParentId)
                 .Select(b => new { 
                                     ParentId = b.Key, 
                                     CreatedDate = b.Max(t => t.CreatedDate) 
                                  }))
     on a.ParentId equals b.ParentId
     where a.CreatedDate == b.CreatedDate
     select a);

这样可以检索我需要的东西,但我怀疑有一种更优雅的方式来完成这项任务。有哪些替代方法可以做到这一点?非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

我可能会这样做:

订购所有记录,以便最先记录最先记录,然后排在最前面。

var q = (from a in myTable
         where a.ParentId != null
         orderby a.CreatedDate descending
         select a).Take(1).ToList();

应该生成类似于以下内容的SQL:

SELECT TOP 1 *
FROM MyTable a
WHERE a.CreatedDate IS NOT NULL
ORDER BY a.CreatedDate DESC

<强>更新

啊,所以你想要每组相关孩子的最新孩子。那么这样的事情应该可以解决问题。我想Take方法适用于您的提供商。似乎FirstOrDefault似乎没有实现,因为您已经尝试过了。

var q =
    from t in myTable
    where t.ParentId != null
    group t by t.ParentId into grp
    select grp.OrderByDescending(p => p.CreatedDate).Take(1);