【问题标题】:How can I convert DateTime to String in Linq Query?如何在 Linq Query 中将 DateTime 转换为字符串?
【发布时间】:2014-10-01 17:00:56
【问题描述】:

我必须以MMM dd,YYYY 格式显示日期。

var performancereviews = from pr in db.PerformanceReviews
                                         .Include(a => a.ReviewedByEmployee)
                                 select new PerformanceReviewsDTO
                                 {
                                     ReviewDate=pr.ReviewDate.ToString("MMM dd,yyyy"),
                                     EmployeeName=pr.ReviewedByEmployee.Name,
                                     JobTitle=pr.ReviewedByEmployee.JobTitle,
                                     ReviewerComments=pr.CommentsByReviewer,
                                     EmployeeComments=pr.CommentsByEmployee
                                 };

这是我收到的错误消息

ExceptionMessage:LINQ to Entities 无法识别方法“System.String ToString(System.String)”方法,并且此方法无法转换为存储表达式。 异常类型: System.NotSupportedException

当我在pr.ReviewDate 上应用ToString 时出现错误。

请用适当的解决方案指导我如何做到这一点。我知道在普通的 C# 编码中有几个可用的选项,但在 Linq 中我们怎么做。

【问题讨论】:

  • 一般显示格式化是在display逻辑中执行的,而不是在查询数据的时候。 PerformanceReviewsDTO.ReviewDate 的类型是什么?这段代码给你什么错误?
  • @David 我知道类型如果存储字符串类型值,那么它肯定应该是字符串,它是字符串这里是错误异常消息:LINQ to Entities 无法识别方法'System.String ToString( System.String)' 方法,并且此方法不能转换为存储表达式。异常类型:System.NotSupportedException
  • 为什么有人投反对票,请不要忘记在投反对票时给 cmets。

标签: c# linq entity-framework linq-to-entities


【解决方案1】:

发生这种情况是因为 LINQ to Entities 正在尝试将表达式树转换为 SQL 查询,而 .ToString() 可以转换为 SQL,.ToString(string)不能时间>。 (SQL 没有相同的字符串格式化概念。)

要解决此问题,请不要在查询中执行格式化,而是在显示逻辑中执行。使查询尽可能简单:

select new PerformanceReviewsDTO
{
    ReviewDate=pr.ReviewDate,
    EmployeeName=pr.ReviewedByEmployee.Name,
    JobTitle=pr.ReviewedByEmployee.JobTitle,
    ReviewerComments=pr.CommentsByReviewer,
    EmployeeComments=pr.CommentsByEmployee
}

在这种情况下,PerformanceReviewsDTO.ReviewDate 仍然是 DateTime 值。它不是格式化数据,只是携带它。 (就像 DTO 应该做的那样。)

然后,当您显示该值时,执行格式化。例如,这是在 MVC 视图中使用的吗?:

@Model.ReviewDate.ToString("MMM dd,yyyy")

您甚至可以在PerformanceReviewsDTO 中添加一个简单的属性来进行格式化显示:

public string FormattedReviewDate
{
    get { return ReviewDate.ToString("MMM dd,yyyy"); }
}

然后任何绑定到 DTO 上的属性的东西都可以绑定到它(假设在这种情况下它是单向绑定)。

【讨论】:

  • 感谢 David 的回答我已经从 Web Api 中返回数据,在 Web Api 中我只有这个地方可以将其转换为我的移动应用程序视图中所需的正确格式。你可以看到我是已经使用 DTO(数据传输对象)我正在寻找 Haedrian 解决方案来弄清楚如何做到这一点。
  • @ProgrammingNinja:我最后建议向 DTO 添加属性应该满足该要求。当 WebAPI 序列化发生时,它应该序列化 FormattedReviewDate 属性以及 ReviewDate 属性。 (如果命名很重要,您可以将它们分别更改为ReviewDatePersistedReviewDate,因此使用代码不必更改。)至于其他发布的答案,请注意cmets。它可以“起作用”,但也可能产生严重的副作用。
  • 很好的答案感谢您花时间解决我的问题。
  • 但是,如果需要通过来自客户端的字符串进行过滤,例如由“十月”))
【解决方案2】:

我通常解决这个问题的方法是首先获取数据,然后在内存中选择它。

var performancereviews = from pr in db.PerformanceReviews
                                      .Include(a => a.ReviewedByEmployee)
                                      .ToArray()
                                      .Select( ....);

通过将ToArray(或 List 或其他)放入,它将完成 sql 查询部分,然后从内存中的集合中完成其余部分 - 这应该没问题。

【讨论】:

  • 请记住,如果系统当前没有将整个集合具体化(我们无法判断,那么将整个集合具体化到内存中很容易对性能产生负面影响)来自发布的代码)。
  • 这会导致在Select 中完成的任何其他工作都不会在数据库上执行,特别是对返回哪些列的限制。
  • 投赞成票,因为有时这是一种明智的方法,仅仅是因为您可能无法控制显示逻辑,或者您的规格可能会迫使您这样做(因为我刚刚不得不做)。我不喜欢这样做,但在这件事上我别无选择。
  • 然而,作为记录,如果你可以在显示逻辑中做到这一点,我完全赞成,但没有理由你的答案应该在负数恕我直言。
猜你喜欢
  • 2011-10-16
  • 2021-03-31
  • 2012-05-05
  • 1970-01-01
  • 2014-03-01
  • 2021-10-28
  • 2019-11-28
  • 2021-12-12
  • 1970-01-01
相关资源
最近更新 更多