【问题标题】:Calculate elapsed time in a linq query计算 linq 查询中经过的时间
【发布时间】:2017-12-21 19:40:45
【问题描述】:

在 .Net Core 应用程序中使用 System.Linq 我尝试将 AssignedDate 和 DateTime.Now 之间的日期差异放入 ElapsedTime。

var query = from r in _context.Request
    join st in _context.ServiceType on r.ServiceTypeId equals st.ServiceTypeId
    join u in _context.Users on r.AssignedUserId equals u.UserId into ju
    from u in ju.DefaultIfEmpty()
            select new RequestDto
            {
                RequestId = r.RequestId,
                UserId = r.UserId,
                //..
                AssignedUserId = r.AssignedUserId.Value,
                AssignedUser = u.Name,
                ElapsedTime = DateDiff(r.AssignedDate, DateTime.Now)
    };

DateDiff 不是一个有效的函数。我将如何替换它?

编辑:使用 MicrosoftEntityFrameworkCore 2.0。尝试 EntityFunction 无效。

再次编辑:我可以在视图侧使用剃须刀,例如:

@if (item.AssignedDate != null){@DateTime.Compare(item.AssignedDate.Value, DateTime.Now)}

但这不起作用??

【问题讨论】:

  • 看起来您正在使用 EF Core。请更新标签并指定 EF Core 版本。
  • DateTime - DateTime = TimeSpan...
  • 差异应该以小时、天、...为单位吗?
  • EntityFrameworkCore 2.0 |差异应显示在 Minutes:Seconds
  • 我个人认为“核心”产品还没有为大多数数据库使用做好准备。他们添加了EF.Functions 功能和DBFunctions 注册功能,但我认为它与标准化的EntityFunctions 相比没有竞争力。

标签: c# linq asp.net-core ef-core-2.0


【解决方案1】:

不幸的是,即使在目前最新的 EF Core 2.0.1 中,EF Core 中的 TimeSpanDateTime 操作支持仍然远远不够完美。

例如,自然

ElapsedTime = DateTime.Now - r.AssignedDate

for SqlServer throws SqlException - “数据类型 datetime 和 datetime2 在减法运算符中不兼容。”.

并尝试使用变量来欺骗它

var baseDate = DateTime.Now;

然后

ElapsedTime = baseDate - r.AssignedDate

导致另一个SqlException - “操作数数据类型 datetime2 对减法运算符无效。”.

我能够使用没有错误的唯一方法是DateTime.Subtract 方法:

ElapsedTime = DateTime.Now.Subtract(r.AssignedDate)

但请记住,这会导致client evaluation

【讨论】:

  • 哦,我没有意识到 EF Core 执行了客户端评估而不是抛出异常。我可以看到很多人因此而遇到性能问题......
  • @DavidG 确实。有一种方法可以禁用它,但是在 SQL 转换的当前状态下,EF Core 将实际上无法使用。
  • 开始认为我应该切换到 Dapper 以获得一些即将开始的 donet 核心 Ubuntu 开发...... :)
【解决方案2】:

假设你可以改变ElapsedTime的类型,怎么样:

...
ElapsedTime = (DateTime.Now - r.AssignedDate).Ticks

ElapsedTime 必须是long 类型,这将与ticks 保持差异,当你读回它时,你可以使用TimeSpan.FromTicks(ticksValue),然后你可以选择你想要的成员(小时,分钟, 秒, 分数等...)

【讨论】:

  • TimeSpan.net 类型,我不明白为什么它不会,但我没有用 EF 测试过。
  • 虽然它不是 SQL 类型,但这就是问题所在。如果它不适用于 EF,那么这将引发异常。
  • ElapsedTime 作为 TimeSpan 与您提供的表达式会产生错误,“无法将类型为“Sytem.DateTime”的对象转换为类型“System.TimeSpan”。
  • @P-Finny,我刚刚更新了我的答案,再试一次。
  • @DavidG 这理论上应该在 EF Core 中工作,但目前它并没有,并且正如你所猜测的那样抛出异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-25
  • 2020-12-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
  • 2010-11-15
相关资源
最近更新 更多