【问题标题】:EF CORE LINQ date comparison with new DateTime(yearId, monthId, dateId)EF CORE LINQ 日期与新 DateTime(yearId, monthId, dateId) 的比较
【发布时间】:2020-03-31 18:59:11
【问题描述】:

我正在尝试在 EF 上下文中针对 DbSet 执行 LINQ 查询。 DbSet类中的LastDAyToEnterData类有3个short类型的get/set属性,映射到一个SQL Server表,有3个smallint类型的列,分别代表年、月、日。当我在.Where() 中使用表达式时,我得到了这个错误。我应该使用什么表达式来比较两个日期?谢谢。

无法翻译 LINQ 表达式。以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估。请参阅https://go.microsoft.com/fwlink/?linkid=2101038 了解更多信息。

DbSet<LastDayToEnterData>
    .Where(l => new DateTime(
        (int)l.YearID, 
        (int)l.MonthID, 
        (int)l.StopEnteringDataAfter
    ) > new DateTime(
        DateTime.Today.Year - 1, 
        10, 
        1
    ))

【问题讨论】:

  • 由于时间限制,我放弃了将yearid、monthid和stopEnteringDateAfter转换为真实DateTime的方法。我会尝试其他时间。非常感谢。

标签: c# linq asp.net-core


【解决方案1】:

无法翻译 LINQ 表达式。以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估。请参阅https://go.microsoft.com/fwlink/?linkid=2101038 了解更多信息。

原因是 EF Core 3 中禁用了隐式客户端评估。

参考:

https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/breaking-changes#linq-queries-are-no-longer-evaluated-on-the-client

作为一种解决方法,您可以进行如下更改:

1.型号:

public class LastDayToEnterData
{
    public int Id { get; set; }
    public int YearID { get; set; }
    public int MonthID { get; set; }
    public int StopEnteringDataAfter { get; set; }
    public string Name { get; set; }
}

2.控制器:

var date = _context.LastDayToEnterData.Select(u => new { u.MonthID, u.YearID, u.StopEnteringDataAfter,u.Id }).ToList();
var list = new List<LastDayToEnterData>();
foreach(var d in date)
{
    var ConvertDate = new DateTime(d.YearID,d.MonthID, d.StopEnteringDataAfter);
    if(ConvertDate > new DateTime(DateTime.Today.Year - 1, 10, 1))
    {
        var data = _context.LastDayToEnterData
                           .Where(l => d.Id == l.Id).FirstOrDefault();
        list.Add(data);
    }               
}

【讨论】:

    【解决方案2】:

    您需要使用DbFunctions.CreateDateTime 来创建新的 DateTime 对象并从 Linq 中投射出比较日期:

    var compareDate = new DateTime(DateTime.Today.Year - 1, 10, 1);
    
    DbSet<LastDayToEnterData>
        .Where(l => EntityFunctions.CreateDateTime(
            (int)l.YearID, 
            (int)l.MonthID, 
            (int)l.StopEnteringDataAfter
        ) > compareDate )
    

    【讨论】:

    • 我把它改成了 .Where(System.Data.Entity.Core.Objects.EntityFunctions.CreateDateTime(x.YearID, x.MonthID, x.StopEnteringDataAfter,0,0,0) >= _fyStartDate ) 但仍然没有运气。它还说 EntityFunctions 已过时,应替换为 System.Data.Entity.DbFunctions。那也没用。
    • 我已经更新了我的答案,您还需要从 linq 中预测出您的比较日期。
    • 由于时间限制,我放弃了将yearid、monthid和stopEnteringDateAfter转换为真实DateTime的方法。我会尝试其他时间。非常感谢。
    猜你喜欢
    • 2017-06-27
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    • 2016-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多