Linq to Entities 4.1 - 组查询强制排序

时间:2011-06-08 21:08:53

标签: c# entity-framework linq-to-entities group-by ef-code-first

我正在使用Entity Framework 4.1 Code First开发应用程序。问题是当我尝试对查询进行分组时,它会使用组密钥自动添加订单,从而覆盖以前的orderby语句。这是查询:

using (var database = new Database())
{
    var query = from frame in database.Set<Frame>()
                orderby frame.DtStart, frame.DtStartMs
                group frame by frame.ReadoutID;
    Console.WriteLine(query.ToTraceString());
}

当我查看生成的sql(拦截dbquery的objectquery)时,我得到以下内容:

SELECT
`Project2`.`devices_leituras_key`,
`Project2`.`C1`,
`Project2`.`devices_frames_key`,
`Project2`.`devices_key`,
`Project2`.`devices_leituras_key1`,
`Project2`.`devices_arquivos_key`,
`Project2`.`init_byte_arquivo`,
`Project2`.`dt_inicio`,
`Project2`.`dt_inicio_ms`,
`Project2`.`dt_fim`,
`Project2`.`dt_fim_ms`
FROM (SELECT
`Distinct1`.`devices_leituras_key`,
`Extent2`.`devices_frames_key`,
`Extent2`.`devices_key`,
`Extent2`.`devices_leituras_key` AS `devices_leituras_key1`,
`Extent2`.`devices_arquivos_key`,
`Extent2`.`init_byte_arquivo`,
`Extent2`.`dt_inicio`,
`Extent2`.`dt_inicio_ms`,
`Extent2`.`dt_fim`,
`Extent2`.`dt_fim_ms`,
CASE WHEN (`Extent2`.`devices_frames_key` IS  NULL) THEN (NULL)  ELSE (1) END AS `
C1`
FROM (SELECT DISTINCT
`Extent1`.`devices_leituras_key`
FROM `devices_frames` AS `Extent1`) AS `Distinct1` LEFT OUTER JOIN `devices_frames`
AS `Extent2` ON `Distinct1`.`devices_leituras_key` = `Extent2`.`devices_leituras_key
`) AS `Project2`
 ORDER BY
`devices_leituras_key` ASC,
`C1` ASC

请注意,表格的框架POCO之间存在一些映射,例如“readoutID”属性与“devices_leituras_key”。但是,字段C1不存在于表中。

问题: 为什么缺少指定的排序(orderby frame.DtStart,frame.DtStartMs)? 为什么ReadoutID与其他奇怪的字段排序(ORDER BY devices_leituras_key ASC,C1 ASC)出现?

当我删除分组时,原始顺序正常显示。

提前致谢

1 个答案:

答案 0 :(得分:1)

LINQ-to-SQL和LINQ-to-Entities使用远程模型。查询中的序列实现IQueryable,并在编译后从Queryable类解析为查询运算符,称为表达式树。表达式树由运行时解释

更改查询中的顺序,您应该没问题:

using (var database = new Database())
{
    var query = from frame in database.Set<Frame>()
    group frame by frame.ReadoutID;
    orderby frame.DtStart, frame.DtStartMs

    Console.WriteLine(query.ToTraceString());
}