2014-10-01 148 views
7

我在MMM dd,YYYY格式来显示日期。如何将DateTime转换为Linq查询中的字符串?

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到实体无法识别方法“System.String的ToString(System.String)”的方法,而且这种方法不能被翻译进入商店表达。 ExceptionType: System.NotSupportedException

,当我在pr.ReviewDate申请ToString我得到的错误。

请指引我正确的解决办法,我怎么能做到这一点。我知道在正常的C#编码中有几种可用的选项,但在Linq中,我们该如何做到。

+0

一般显示格式将在*显示*逻辑来执行,而不是查询数据时。什么是“PerformanceReviewsDTO.ReviewDate”的类型?这段代码给你什么错误? – David 2014-10-01 17:04:09

+0

@大卫我知道类型的,如果我存储字符串类型值,那么definitly它应该是字符串,它是这里的字符串是错误ExceptionMessage: LINQ到实体无法识别方法“System.String的ToString(System.String)”的方法,并且此方法不能转换为商店表达式。 例外类型: 系统。NotSupportedException – ProgrammingNinja 2014-10-01 17:06:28

+0

为什么有人低估,请不要忘记在downvoting时给予评论。 – ProgrammingNinja 2014-10-01 17:17:49

回答

13

这是发生,因为LINQ到实体试图表达式树转换成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可以与之绑定(假设在这种情况下它是单向绑定)。

+0

谢谢大卫回答我已经从Web Api和Web Api中返回数据我只有这个地方将它转换为适合我的视图中移动应用程序所需的格式。您可以看到我正在使用DTO(数据传输对象)我已经在寻找Haedrian解决方案了解如何去做。 – ProgrammingNinja 2014-10-01 17:15:58

+0

@ProgrammingNinja:我最后一次向DTO添加属性的建议应该满足这个要求。当WebAPI序列化发生时,它应该序列化'FormattedReviewDate'属性以及'ReviewDate'属性。 (如果命名很重要,可以分别将它们更改为'ReviewDate'和'PersistedReviewDate',因此消费代码不必更改。)至于其他发布的答案,请注意评论。它可以“工作”,但也可能有严重的副作用。 – David 2014-10-01 17:18:26

+0

非常感谢您花时间解决我的问题。 – ProgrammingNinja 2014-10-01 17:25:11

1

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

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

通过将ToArray(或列表或其他),它会完成SQL查询部分,然后从内存中的集合休息 - 这应该是罚款。

+6

请记住,如果系统目前没有实现整个事物(我们无法从发布的代码中看出),那么将整个集合实现到内存中可能会对性能产生负面影响。 – David 2014-10-01 17:12:56

+2

这导致在数据库上执行'选择'时没有其他工作,特别是返回哪些列的限制。 – Servy 2014-10-01 17:15:46

+0

有投票权,因为有时候这是一个敏感的方法,只是因为你可能没有控制显示逻辑,或者你的规格可能迫使你这样做(正如我刚才所做的那样)。我不喜欢这样做,但我在这件事上没有多少选择。 – shawty 2017-07-18 19:07:08