1

我可以,如果可以的话,如何编写这样的 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 是标签列表

4

3 回答 3

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()是众多选择之一。

于 2013-03-14T18:50:53.070 回答
2

简而言之,不,因为 EF 需要能够将您的 Linq 谓词转换为 T-SQL(或您的 RDBMS 使用的任何 SQL 方言)。仅支持 .NET BCL 函数的子集(例如String.Contains自定义用户代码是正确的)。

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

于 2013-03-14T18:51:22.177 回答
0

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

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

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

于 2013-03-14T18:51:02.860 回答