LINQ自定义函数在.where

时间:2013-03-14 18:47:01

标签: asp.net-mvc linq entity-framework

我可以,如果可以,怎么样,写这样的LINQ语句:

public IQueryable<Advert> SearchSimilarAdverst(string query)
    {
        Levenshtein compute = new Levenshtein();
        return _db.Adverts.Where(a => a.IsActive  && 
              (compute.FindSimilarity(a.Name, query) <= 2));
    }

谢谢

修改

我已经厌倦了解决方案Jeffery建议并且它有效但是当我尝试了这行代码时,我得到了EntityCommandExecutionException,有人知道为什么吗?

adverts.Where(a => a.WhoAmILookingForTags.Any
             (t => compute.FindSimilarity(t.Name,query) <= 2));

标签和广告与多对多关系相关联,而WhoAmILookingForTags是标签列表

3 个答案:

答案 0 :(得分:3)

EF无法将compute.FindSimilarity(a.Name, query)转换为SQL,因此您将不得不接受性能损失并执行以下操作。

public IEnumerable<Advert> SearchSimilarAdverst(string query)
{
    Levenshtein compute = new Levenshtein();
    var adverts = _db.Adverts.Where(a => a.IsActive).ToList();
    return adverts.Where(a => compute.FindSimilarity(a.Name, query) <= 2));
}

注意,还需要更改方法的返回类型以反映返回类型

如下所述,由于执行延迟,应在使用FindSimilarity进行过滤之前强制执行查询。 query.ToList()是众多选项之一。

答案 1 :(得分:2)

简而言之,不 - 因为EF需要能够将您的Linq谓词转换为T-SQL(或您的RDBMS使用的任何SQL语言)。仅支持.NET BCL功能的一部分(例如String.Contains,自定义用户代码右侧)。

对于复杂的谓词,我建议手工编写自己的SQL - 你也会获得更好的性能,EF在生成SQL时会很慢。

答案 2 :(得分:0)

我希望我错了,但我不相信你会在Linq-to-Entities查询中被允许这样做。在这些LINQ查询中,它必须将Where函数中的所有内容转换为要在底层数据库上运行的SQL语句。由于你的方法不是SQL方面的东西,所以当你尝试这个时它会引起异常。

对于常规的LINQ查询(即在所有内容都已被放入内存之后),完成此操作应该没有问题。

您也可以尝试一下,看看它是否有用......