Linq-to-Entities查询中的格式化日期会导致异常

时间:2011-04-30 03:58:50

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

我有提交日期时间的Entity类,我想选择不同的'mon-yyyy'格式的datetime字段值并填充下拉列表。

以下代码给出了错误:

var env = db.Envelopes.Select(d => new
        {
            d.ReportDate.Year,
            d.ReportDate.Month,
            FormattedDate = d.ReportDate.ToString("yyyy-MMM")
        }).Select(d => d.FormattedDate)

    List<SelectListItem> _months = new List<SelectListItem>();         

    foreach (var mname in env)
    {
        _months.Add(new SelectListItem() { Text = mname, Value = mname });
    }

错误讯息:

  

LINQ to Entities无法识别   方法'System.String   ToString(System.String)'方法,和   这种方法无法翻译成   商店表达。

如何更正此错误消息?

由于 SR

4 个答案:

答案 0 :(得分:13)

请记住,您的查询将被转换为SQL并发送到数据库。查询不支持您尝试格式化日期,这就是您看到特定错误消息的原因。您需要检索结果,然后在实现数据后进行格式化。

一种选择是简单地选择日期。在迭代结果时,在将其添加到列表时对其进行格式化。但是,您也可以使用方法链接在单个语句中使用格式化日期来构建列表。

List<SelectListItem> _months = db.Envelopes.OrderByDescending(d => d.ReportDate)
        .Select(d => d.ReportDate)
        .AsEnumerable() // <-- this is the key method
        .Select(date => date.ToString("MMM-yyyy"))
        .Distinct()
        .Select(formattedDate => new SelectListItem { Text = formattedDate, Value = formattedDate })
        .ToList(); 

方法.AsEnumerable()将强制执行查询的第一部分对数据库,其余部分将在内存中处理结果。

答案 1 :(得分:9)

这是另一种选择:

.Select( p -> SqlFunctions.StringConvert((double)
                  SqlFunctions.DatePart("m", p.modified)).Trim() + "/" +
              // SqlFunctions.DateName("mm", p.modified) + "/" + MS ERROR?
              SqlFunctions.DateName("dd", p.modified) + "/" +
              SqlFunctions.DateName("yyyy", p.modified)

显然DateName("MM", ..)拼出了DatePart("mm", ..)提供数字值的月份名称,即StringConvert( ),但是这左边用空格填充结果,因此.Trim()

就像Anthony Pegram上面所说,这发生在数据库而不是C#中(.AsEnumerable()将所有数据都提取到C#,因此请确保在使用之前过滤数据。)

显然,您需要稍微重新排列输出以适合yyyy-MM,并使用DatePart作为数字,使用DateName作为月份名称。

答案 2 :(得分:1)

这是使用常见dd / MM / yyyy格式的替代方案。 在带有Entity Framework 5的SQL Server 2012上确认

invoices.Select(i => new 
{
    FormattedDate = (     EntityFunctions.Right(String.Concat(" ", SqlFunctions.StringConvert((double?) SqlFunctions.DatePart("dd", i.DocumentDate))), 2)
                        + "/"
                        + EntityFunctions.Right(String.Concat(" ",SqlFunctions.StringConvert((double?) SqlFunctions.DatePart("mm", i.DocumentDate))), 2)
                        + "/"
                        + EntityFunctions.Right(SqlFunctions.StringConvert((double?) SqlFunctions.DatePart("yyyy", i.DocumentDate)), 4)
                       ).Replace(" ", "0")
}

使用前导零以dd / MM / yyyy格式生成日期。

答案 3 :(得分:0)

我使用了一种解决方法来手动构建包含yyyyMM的格式。我想在这里提一下它是否可以帮助某人(至少是暂时的):

FormattedDate = d.ReportDate.Year.ToString() + "-" + d.ReportDate.Month.ToString()

这使格式为yyyy-MM