【问题标题】:How can I create a DateTime value in a Linq Query?如何在 Linq 查询中创建 DateTime 值?
【发布时间】:2013-10-09 01:50:53
【问题描述】:

我正在尝试在 Linq to Entities 中创建一个查询。我希望它返回包含从我正在查询的表中的字符串派生的 DateTime 属性的对象。数据(在 SQL Server 中)有一个名为 date_occurred 的字符串日期字段(在数据库中显示为 VARCHAR(8))。它有一个名为 time_occurred 的字符串时间字段 (varchar(6))。

date_occurred 的内容示例为“20131007”,表示 2013 年 10 月 7 日。time_occurred 的内容示例为“145710”,表示下午 2:57 后 10 秒。

我尝试了两种不起作用的方法:

Dim ATQuery = From e In EntityContext.vwSecAppAuditToday
   Order By e.date_occurred, e.time_occurred
   Select New AuditEntry With {
      .EventTime = DateTime.ParseExact(Trim(e.date_occurred) & Trim(e.time_occurred), "yyyyMMddHHmmss", CultureInfo.InvariantCulture),
      .ServerName = e.server_name
}

这会引发 NotSupportedException 并显示一条消息:“LINQ to Entities 无法识别方法 'System.DateTime ParseExact(System.String, System.String, System.IFormatProvider)' 方法,并且无法翻译此方法到商店表达式中。”

在此之前,我尝试过:

Dim ATQuery = From e In EntityContext.vwSecAppAuditToday
   Order By e.date_occurred, e.time_occurred
   Select New AuditEntry With {
      .EventTime = New DateTime(Integer.Parse(e.date_occurred.Substring(0, 4)),
         Integer.Parse(e.date_occurred.Substring(4, 2)),
         Integer.Parse(e.date_occurred.Substring(6, 2)),
         Integer.Parse(e.time_occurred.Substring(0, 2)),
         Integer.Parse(e.time_occurred.Substring(2, 2)),
         Integer.Parse(e.time_occurred.Substring(4, 2))),
      .ServerName = e.server_name
}

这也会引发NotSupportedException。在这种情况下,消息指出:“LINQ to Entities 中仅支持无参数构造函数和初始化程序。”

我正在尝试使用 Linq to Entities 来实现吗?

编辑:评论提醒

对于那些后来阅读这篇文章的人来说,Moho 和 Matt Johnson 制作了特别有用的 cmets。我已将这些标记为 +1。

【问题讨论】:

  • 你能告诉我们e.date_occurede.time_occured的内容吗?
  • 很好的建议。我会编辑帖子。谢谢!
  • 您使用的是什么数据库,您使用的列是什么数据库类型?
  • 是否有某些原因您不能使用正确的 SQL 数据类型,例如 DATETIME
  • 应该可以。请务必在该视图上为已翻译的列添加索引。

标签: vb.net linq entity-framework


【解决方案1】:

选择一个包含感兴趣字段的匿名类(称为投影),然后在枚举 IQueryable 后为每个项目创建 DateTime 结构:

Dim ATQuery = From e In EntityContext.vwSecAppAuditToday
   Order By e.date_occurred, e.time_occurred
   Select New With {
      .DateOccurred = e.date_occurred,
      .TimeOccurred = e.time_occurred,
      .ServerName = e.server_name
}

Dim q2 = From e In ATQuery.ToArray()
         Select New AuditEntry With {
             .EventTime = DateTime.ParseExact(Trim(e.DateOccurred) & Trim(e.TimeOccurred), "yyyyMMddHHmmss", CultureInfo.InvariantCulture),
             .ServerName = e.ServerName
}

【讨论】:

  • 它有效,我很高兴——谢谢!但为什么?是不是因为 ParseExact 调用现在是在查询数组数据而不是实体框架?
  • 是的 - 您必须记住,当使用 EF DbContext 时,您的 IQueryable 表达式将被转换为 SQL 语句。您遇到的错误是由于 EF Linq to Entities 查询提供程序不知道如何将您的 int.ParseDateTime.ParseExact 调用转换为 SQL,因为它们是 .NET 结构。通过调用.ToArray() 枚举原始数据库查询,您可以查询数据库并在本地(在内存中)获取结果,然后您可以使用所有您认为合适的 .NET 语言工具
  • 我认为AsEnumerableToArray 更可取?
【解决方案2】:

您的 New DateTime 仅包含整数,因此它看起来像 20131008011300(对于 2013/10/08 01:13:00)

日期和时间之间的/、时间之间的:和日期和时间之间的space都错过了

【讨论】:

  • 谢谢,但我还是有点困惑:我认为我提供给 ParseExact 方法的格式字符串解释了它正在解析的简单数字字符串格式。此外,异常消息指出 Linq“无法识别该方法”。 ParseExact 是否不适用于不包含斜杠、冒号和空格的格式字符串?
  • 根据异常消息,Linq 在可能出现在 Linq 查询中的代码中似乎非常有选择性。
  • 这不是 linq 查询,这是 linq to entity 查询
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多