我有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中映射和使用它?
我只想在数据库中执行不区分大小写的搜索,以保持良好的性能。
提前致谢。
答案 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看作一个优秀的搜索服务提供商。