如何使用Entity Framework实现搜索功能?

时间:2011-08-10 18:27:20

标签: c# linq entity-framework entity-framework-4 linq-to-entities

我有blog application使用Entity Framework为数据库建模。这个博客的问题是找到我正在寻找的东西变得很困难。它需要一个搜索功能,但我不确定如何使用SQL和/或LINQ to Entities来实现它。

现在我正在使用这个LINQ查询搜索我的数据库,但它似乎应该更好。

    public IEnumerable<BlogPost> SearchBlogPosts(string query, int page, int itemsPerPage)
    {
        var result = _dataContext.BlogPosts
            .Where(BlogPostContains(query))
            .OrderByDescending(x => x.PostedDate)
            .Skip((page - 1) * itemsPerPage)
            .Take(itemsPerPage),
        return result;
    }

    private Func<BlogPost, bool> BlogPostContains(string query)
    {
        return x => x.Title.Contains(query) || x.Body.Contains(query) || x.Author.Contains(query);
    }

这个问题的一大问题是搜索区分大小写。

问题1)有没有更好的方法来使用LINQ to Entities进行搜索?

问题2)只用普通的SQL怎么样?我如何在SQL Server中编写搜索存储过程,以便我可以在EF而不是LINQ中映射和使用它?

我只想在数据库中执行不区分大小写的搜索,以保持良好的性能。

提前致谢。

4 个答案:

答案 0 :(得分:5)

此标准方法是SQL全文搜索。您必须在数据库上启用全文,指定列为全文索引,然后才能使用这些列使用SQL Contains查询。

Linq to Entities目前不支持全文搜索查询 - 您必须为此采用标准SQL查询。您可以使用ExecuteStoreQuery()至少将搜索结果映射到键入的结果。

答案 1 :(得分:3)

SQL Server的默认排序规则不区分大小写,这意味着像这样的where子句(这是LINQ to Entities将从Contains创建的)...

where Name like '%JOHN%'

......应该找到“约翰韦恩”。我相信您的查询不是在服务器上执行,而是实际上在内存中使用LINQ to Objects - 并且搜索区分大小写。这是对象的LINQ,因为您没有从Expression返回BlogPostContains。签名应该是:

private Expression<Func<BlogPost, bool>> BlogPostContains(string query)

如果您只返回Func<BlogPost, bool>,那么您正在使用IEnumerable扩展方法的IQueryable(而不是Where)重载,这会导致整个BlogPosts {1}}表首先加载到内存中。然后使用LINQ to Objects将过滤器应用于内存中。

如果您返回Expression

是否会消除区分大小写会很有趣

(正如关于您的案例敏感度问题的说明,而不是关于实施搜索功能的最佳方式的一般问题的解决方案。)

答案 2 :(得分:0)

根据你使用LINQ的搜索,你可以尝试这样的东西,它可以正常工作:

(x.Title).ToUpper().Contains(query.ToUpper())

ToLower()的类似方法也应该足够了。

对于真正认为大写'A'与小写'a'不同的数据库作为不同的值,从技术上讲,上面的LINQ过程将为您提供结果。

希望这会有所帮助。

答案 3 :(得分:-1)

我会把Lucene.Net看作一个优秀的搜索服务提供商。