2

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

例如。PersonTable:DateOfBirth=01/04/1972,DateToCalculateAge=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 计算年龄,而是从数据库中的日期计算年龄。

4

2 回答 2

8

由于您使用的是 LINQ to Entities,因此首选的解决方案是利用System.Data.Objects.EntityFunctionsEF 版本 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)
    )
)

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

于 2012-05-15T13:33:06.020 回答
0

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

.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()将查询带入内存,您将能够使用这些方法。

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

于 2012-05-15T13:37:04.150 回答