【问题标题】:How to call a method in the where clause of a LINQ query on a IQueryable object如何在 IQueryable 对象上的 LINQ 查询的 where 子句中调用方法
【发布时间】:2011-10-25 12:29:15
【问题描述】:

我有一个通过 EF 4.1 获得的 MyType 的 IQueryable。

我通过 linq 以 where 子句的形式应用过滤器,其中一个将根据与给定邮政编码的距离进行过滤。

MyType 有一个 ZipCode 属性,我需要调用一个方法来计算 MyType 邮政编码和我给定的邮政编码之间的距离。

我尝试了以下方法,它可以编译,但在运行时抛出错误。

myTypes = myTypes.Where(x => GetDistance(x.Zip, givenZip) < 10);

我怎样才能做到这一点?

编辑

My Distance 方法返回一个以英里为单位的双精度值

public double Distance(Position position1, Position position2)
{ 

}

Position 是一个结构,包含 lat 和 long 的双精度值

【问题讨论】:

标签: c# .net linq entity-framework entity-framework-4.1


【解决方案1】:

如果GetDistance() 返回一个布尔值,这应该在 Linq to Objects 中工作 - 它不适用于 Linq to Entities,因为它会尝试将您的方法映射到 SQL 等价物,当然没有。

作为一种粗略的解决方法,您可以使用AsEnumerable(),但这会实现您的所有类型,因此如果您的表较大,则不建议这样做:

myTypes = myTypes.AsEnumerable()
                 .Where(x => GetDistance(x.Zip, givenZip) < 10);

另一种方法是将邮政编码映射到数据库中的地理位置,并直接将这些位置与soon to be supported spatial data types 一起使用——我认为这可能是最好的方法,但还不能用于生产。当然,如果您仅限于 SQL Server,您可以直接使用商店查询来使用地理位置 - 但这可以解决 EF。

【讨论】:

  • .NET 4.5 将支持那些新支持的空间数据类型。任何适合生产的版本尚不支持它们。
  • 谢谢,我刚改成 .AsEnumerable() 它解决了我的问题。
【解决方案2】:

这将引发错误,因为运行时会尝试将您的表达式树转换为 SQL。函数“GetDistance”无法转换。

看看Model Defined Functions。它们允许您在 edmx 中定义一个自定义函数,您可以在构建查询时执行该函数。

【讨论】:

    【解决方案3】:

    假设:

    List<myType> myTypes;
    

    尝试:

    myTypes = myTypes.Where(x => GetDistance(x.Zip, givenZip) < 10).ToList();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-31
      • 2018-08-14
      • 2021-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-15
      相关资源
      最近更新 更多