Linq选择

时间:2017-01-24 14:31:02

标签: c# mysql entity-framework linq

我正在努力将MySQL查询转换为C#中的linq语法(使用实体框架)。 MySQL查询如下所示:

SELECT *
FROM Availability as tableData
WHERE ID = (
SELECT Availability.ID 
FROM Availability 
WHERE Availability.FrameID = tableData.FrameID 
ORDER BY Availability.Date DESC limit 1)

我不知道如何转换此部分FROM table AS someName

到目前为止,我唯一的解决方案是执行原始SQL查询,例如:

dataContext.Availability.SqlQuery("SELECT * FROM Availability as tableData WHERE ID = (SELECT ID FROM Availability WHERE FrameID = tableData.FrameID ORDER BY Availability.Date DESC limit 1)").ToArray();

但是知道linq是否可以提供这样的查询会很高兴。

提前致谢,感谢您的回答!

3 个答案:

答案 0 :(得分:4)

如果您只需要每个帧ID的最新记录,请使用分组:

dataContext.Availability
   .GroupBy(a => a.FrameID)
   .Select(g => g.OrderByDescending(a => a.Date).FirstOrDefault());

此查询产生所需的结果,但生成的sql会有所不同。它看起来像

SELECT /* limit1 fields */
FROM (
    SELECT DISTINCT tableData.FrameID
    FROM Availability as tableData) AS distinct1
OUTER APPLY (
    SELECT TOP(1) /* project1 fields */
    FROM (SELECT /* extent1 fields */
          FROM Availability AS extent1
          WHERE Availability.FrameID = distinct1.FrameID) AS project1
    ORDER BY project1.Date DESC) AS limit1

注意:EF

不支持First()扩展名

答案 1 :(得分:2)

通过FrameId获取所有Avilabilities,按日期对每个组进行排序,获取每个组的第一个条目。 最后的ToList()获取所有结果并将它们放入List中。

var tableDate = dataContext.Availability
               .GroupBy(x => x.FrameId)
               .Select(x => x.OrderByDescending(y => y.Date).FirstOrDefault())
               .ToList();

答案 2 :(得分:1)

是的Linq可以做到这一点,但你需要有一个linq应该运行的起始序列。通常,此序列与您的表具有相同的类型,在您的情况下可用。

从我的sql中我收集到,可用性表中的每条记录至少包含属性Id,FrameId和Date:

class Availability
{
    public int Id {get; set;}
    public int FrameId {get; set;
    public DateTime Date {get; set;}
}

当然这也可以是匿名类型。重要的是你有某种具有这些属性的项目序列:

IQueryable<Availability> availabilities = ...

您写道:

  

每个FrameID我只需要一条记录(最大插入日期)

因此每个可用性都有一个FrameId,并且您希望每个FrameId具有最高Date值的记录。

您可以使用Enumerable.GroupBy并按FrameId分组

var groupsWithSameFrameId = availabilities.GroupBy(availability => availability.FrameId);

结果是一系列组。每个组都包含具有相同FrameId的所有可用性的序列。换句话说:如果您选择一个组,您将拥有一个group.Cey,其中包含FrameId值和具有此FrameId值的所有可用性序列。

我们不会使用该组。键。 如果按日期按降序对每个组中的元素序列进行排序并获取第一个元素,那么您将获得具有最高值的日期

var recordWithMaxDateOfInsert = groupsWithSameFrameId
    .Select(group => group.OrderByDescending(groupElement => groupElement.Date)
    .First();
  

从每个组中按降序日期值对组中的所有元素进行排序,并获取已排序组的第一个元素。

结果:从您的原始可用性开始,您可以为每个frameId提供具有最高日期值的可用性。