LINQ 到实体:LINQ 查询中的期限计算会导致"Method cannot be translated into a store expression"



使用 LINQ to Entities,我需要从 PersonTable 获取记录,其中 Age 介于 AgesFrom 和 AgesTo 之间。问题是,我需要根据存储在数据库中的出生日期和特定的日期计算来计算他们的年龄。

例如。人物表: 出生日期=01/04/1972, 日期计算年龄=25/12/2011

.Where(0 < o.FormDate.AddYears(-agesFrom).CompareTo(o.FormDate.Subtract(o.Person.DateOfBirth)) &&
       0 > o.FormDate.AddYears(-agesTo).CompareTo(o.FormDate.Subtract(o.Person.DateOfBirth));
// ----------------------- OR ------------------------
.Where(agesFrom <= CalculateAge(o.Person.DateOfBirth.Value, o.FormDate) &&
       agesTo >= CalculateAge(o.Person.DateOfBirth.Value, o.FormDate);

对于我提供的代码,我得到以下异常:"LINQ to Entities 无法识别方法'System.DateTime AddYears(Int32('方法,并且此方法无法转换为存储表达式。

我知道一旦 LINQ 将查询传递给数据库,我尝试使用的方法就无法转换。有解决方法吗?我可以在访问数据库后进行过滤,但希望避免这种瓶颈。我还想添加一个 sql 函数来为我完成此计算,但想先穷尽 LINQ 的可能性。

这里有一篇不错的帖子详细介绍了如何在查询之前更好地进行年龄计算:在 LINQ 中检查年龄筛选器的最短方法?但是,在我的情况下,我不是从 DateTime.Now 计算年龄,而是从数据库中的日期计算年龄。

由于使用的是 LINQ to Entities,因此首选解决方案是利用 System.Data.Objects.EntityFunctions 中定义的方法(EF 版本 6 的更新:改用 DbFunctions(,查询图面会成功将它们转换为 SQL。在这种情况下,您需要采取例如:

o.FormDate.AddYears(-agesFrom)
          .CompareTo(o.FormDate.Subtract(o.Person.DateOfBirth))

并将其转换为类似

EntityFunctions.DiffMinutes(
    EntityFunctions.AddYears(o.FormDate, -agesFrom),
    EntityFunctions.AddSeconds(
        o.FormDate, 
        EntityFunctions.DiffSeconds(o.FormDate, o.Person.DateOfBirth)
    )
)

我不确定上述内容是否真的正确,因为它确实伤害了我的眼睛。

不能在 LINQ to Entities 中使用这些方法。但是,如果查询是在内存中完成的,则可以。尝试在.Where之前使用.ToList()

.ToList().Where(0 < o.FormDate.AddYears(-agesFrom)
         .CompareTo(o.FormDate.Subtract(o.Person.DateOfBirth)) && 0 > o.FormDate.AddYears(-agesTo)
         .CompareTo(o.FormDate.Subtract(o.Person.DateOfBirth));

.ToList().Where(agesFrom <= CalculateAge(o.Person.DateOfBirth.Value, o.FormDate) 
          && agesTo >= CalculateAge(o.Person.DateOfBirth.Value, o.FormDate);

这样,.ToList()会将查询带到内存中,您将能够使用这些方法。

如果你有一个庞大的数据库,它的性能会受到影响,但它会起作用。

相关内容

最新更新