如何在LINQ OrderBy中使用外部方法

时间:2017-04-09 13:39:00

标签: c# entity-framework linq

finalProducts = context.Products.OrderBy(p => p.Name.LevenshteinDistance(query))
                                .Skip(from)
                                .Take(36)
                                .ToList<Product>();

我使用方法LevenshteinDistance()来查找与查询的匹配,但它显示错误

  

LINQ to Entities无法识别方法&#39; Int32 LevenshteinDistance(System.String,System.String)&#39;方法,并且此方法无法转换为商店表达式。

如何使用此方法对数据库中的产品进行排序?

3 个答案:

答案 0 :(得分:0)

你正在尝试&#39;使用最可能由您自己编写的方法创建对数据库的查询。但是,问题是框架不知道如何将该方法转换为逻辑查询。从数据库中获得结果后,您需要订购结果。

答案 1 :(得分:0)

您需要订购内存列表:

var products = context.Products.ToList();
var finalProducts = products.OrderBy(p => p.Name.LevenshteinDistance(query)).Skip(from).Take(36).ToList<Product>();

...或者在存储过程中重写方法的逻辑并执行此操作。 LINQ-to-Entities显然无法将您的自定义C#方法转换为T-SQL。

答案 2 :(得分:0)

正如其他人所评论的,问题是您正在尝试在数据库上运行自己的方法。你不能这样做,因为数据库不知道你的方法。

了解Linq2Enties查询的工作原理非常重要。在枚举查询之前,实际上什么也没做。只有当您枚举查询时(例如通过调用类似ToList(),ToArray()或任何几种OrAbc()方法的扩展方法),数据库才会访问数据并将一些结果返回给代码。此时,任何进一步的代码都独立于数据库运行,因此您可以调用自己的方法。

所以,你能做的就是这个......

//> res10: List[String] = List(Vector(83, 80, 66, 69), Vector(67, 66, 77, 77), Vector(77, 70, 78, 80, 79))

那会有效。但是,您需要了解这样做的后果,因为数据库将返回每个产品,如果您有很多,可能需要一些时间。你必须尝试一下,看看这对你来说是否有问题。

如果性能是一个问题,那么你可能不得不将距离函数实现为存储过程,但这还有很多工作要做。首先尝试这种方式。