【问题标题】:Entity framework group by date and return new class实体框架按日期分组并返回新类
【发布时间】:2012-11-24 07:22:30
【问题描述】:

我正在使用 .NET 和实体框架。 我想按没有时间部分的日期对表格进行分组。

我已经上课了:

public sealed class QueryItem {
    public int Year { get; set; }
    public int Month { get; set; }
    public int Day { get; set; }
}

以及方法(我用的是BLToolkit,如果你想知道什么是DbManager):

protected override IQueryable<QueryItem> InitiateQuery() {
    return
        from query in DbManager.GetTable<SomeTableModel>()
        group query by new { Year = query.CreationDate.Year, Month = query.CreationDate.Month, Day = query.CreationDate.Day }
        into list1
        select new QueryItem {Year = list1.Key.Year, Month = list1.Key.Month, Day = list1.Key.Day};
}

在这个方法中linq翻译成这个SQL查询:

SELECT
    [query].[CreationDate]
FROM
    [SomeDatabase.SomeTable] [query]
GROUP BY
    DatePart(Year, [query].[CreationDate]),
    DatePart(Month, [query].[CreationDate]),
    DatePart(Day, [query].[CreationDate]),
    [query].[CreationDate]

这是错误的查询,因为它不仅仅按日期分组。

但是如果我使用这段代码(它不可用,我需要返回一个类对象):

var result =
    from query in DbManager.GetTable<SomeTableModel>()
    group query by new { Year = query.CreationDate.Year, Month = query.CreationDate.Month, Day = query.CreationDate.Day }
    into list1
    select list1;

会翻译成这样:

SELECT
    [t1].[c1] as [c11],
    [t1].[c2] as [c21],
    [t1].[c3] as [c31]
FROM
    (
        SELECT
            DatePart(Year, [selectParam].[CreationDate]) as [c1],
            DatePart(Month, [selectParam].[CreationDate]) as [c2],
            DatePart(Day, [selectParam].[CreationDate]) as [c3]
        FROM
            [SomeDatabase.SomeTable] [selectParam]
    ) [t1]
GROUP BY
    [t1].[c1],
    [t1].[c2],
    [t1].[c3]

这是正确的查询。

我想实体框架试图优化我的查询或类似的东西,这就是我得到错误查询的原因。

我说的对吗? 我是否以正确的方式做这件事? 我该怎么办(可能使用直接 SQL 查询或其他方式)?

【问题讨论】:

    标签: c# .net entity-framework


    【解决方案1】:

    在这里使用EntityFunctions* 要简单得多:

    var result =
        from query in DbManager.GetTable<SomeTableModel>()
        group query by EntityFunctions.TruncateTime(query.CreationDate)
        into list1
        select list1;
    

    *DbFunctions 从实体框架 6 开始。

    【讨论】:

    • 我想它应该可以工作。但是 BLToolkit 失败了。异常消息:'TruncateTime(Convert(selectParam.CreationDate))' 无法转换为 SQL。 堆栈跟踪:_ 在 BLToolkit.Data.Linq.Builder.ExpressionBuilder.ConvertToSql(IBuildContext context, Expression表达式,布尔展开)_我应该考虑如何以另一种方式实现过滤器的UI。
    • 在 EF 中它转换为 convert (datetime, convert(varchar(255), [DateField], 102) , 102))。你能用它在 BLT 中创建一些函数吗?我不清楚 BLT 和 EF 如何合作。遗憾的是,BLT 文档真的很差。
    • 我尝试实现自己的比较器。也失败了。它总是尝试优化查询并失败。但我使用了另一个 UI 和一种过滤数据的方法,现在一切正常。
    【解决方案2】:

    更新答案: EntityFunctions 已弃用。

    警告 1“System.Data.Entity.Core.Objects.EntityFunctions”已过时:“此类已被 System.Data.Entity.DbFunctions 替换。” c:\users\liufa\documents\visual studio 2013\Projects\MatasMrLenderTest\Mvc5MobileApplication1\Controllers\CreditScoreController.cs 32 103 Mvc5MobileApplication1

    现在是DbFunctions

    using System.Data.Entity;
    
    var result = DbManager.GetTable<SomeTableModel>()
    .GroupBy(o => DbFunctions.TruncateTime(o.CreationDate))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-22
      相关资源
      最近更新 更多