在“链接到实体”查询中格式化日期导致异常

本文关键字:格式化 日期 异常 查询 链接 实体 链接到实体 | 更新日期: 2023-09-27 17:53:46

我有一个带有datetime文件的实体类,我想选择不同的'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无法识别方法"System"。字符串ToString(System.String)'方法此方法不能翻译成存储表达式。

如何更正此错误信息?

谢谢SR

在“链接到实体”查询中格式化日期导致异常

请记住,您的查询将被转换为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()将强制对数据库执行查询的第一部分,其余部分将在内存中处理结果。

这里有一个替代方案:

.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作为月份名称。

这里有一个使用常见dd/MM/yyyy格式的替代方法。SQL Server 2012 with Entity Framework 5

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格式生成日期,前导为零。

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

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

这使得格式yyyy-MM