使用Linq,实体框架和数据库索引进行正确搜索

时间:2013-03-28 21:36:56

标签: c# .net linq entity-framework database-design

我需要通过数据库中的产品搜索产品,并且我希望以正确的方式进行设置,以便在存在大量行(1,000,000)时可以获得稳定的性能。我对LINQ和EF有一定的经验,但从来没有编写任何搜索算法,我有以下代码,但只是有一些挥之不去的问题。

context.products.Where(i => i.Name.ToLower().Contains(searchText.ToLower());

我还需要搜索说明。

context.products.Where(i => i.Description.ToLower().Contains(searchText.ToLower());
  1. 此上下文中的.ToLower()会降低性能吗?

  2. 我在NameFullText上有一个常规索引吗?这是否合适,并且常规索引适用于.contains()

  3. 我应该使用LINQ还是其他方法?

  4. 有没有办法可以在名称/描述中获取搜索文本的次数?

  5. 谢谢

3 个答案:

答案 0 :(得分:1)

  1. 请不要使用较低的,因为它会显着影响性能 使用以下之一:

      

    StringComparison.OrdinalIgnoreCase
      StringComparison.CurrentCultureIgnoreCase

  2. 由于您正在使用contains,它将被翻译为'%text%',因此sql server不太可能使用索引。如果您实现FullText搜索,则必须使用存储过程来使用全文搜索的优势。

  3. Linq总是比手写的sql语句慢。我在dapper.net website
  4. 上看到了一些效果指标

    通常,如果您使用的是最新的实体框架,那么您应该获得相当不错的性能,因为它们在版本5中有了一些显着的性能改进。

答案 1 :(得分:1)

我会认真考虑编写一个存储过程来执行此操作,或者使用SqlQuery在DbContext中编写原始sql。如果我正在写这段代码,那就是我要做的。对我来说,EntityFramework和performant从未真正走到一起。

答案 2 :(得分:1)

在我的情况下,我不想使用存储过程。我正在使用Entity Framework,这就是我想要使用的东西!

查看此方法是否可以为您提供帮助。

    public static IQueryable<T> LikeOr<T>(this IQueryable<T> source, string columnName, string searchTerm)
    {
        IEnumerable<string> words =
            searchTerm.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries).Where(x => x.Length > 1);

        var sb = new StringBuilder();
        for (int i = 0; i < words.Count(); i++)
        {
            if (i != 0)
                sb.Append(" || ");

            sb.Append(string.Format("{0}.Contains(@{1})", columnName, i));
        }

        return source.Where(sb.ToString(), words.ToArray());
    }

以上所有方法都会构建一个SQL字符串,然后将其传递给Dynamic LINQ Where方法。在高级别上,所有这一切都允许您仅在需要的地方使用直接sql,而不是在SQL中编写整个查询。 这是通过以下方式调用的:

    public List<Book> SearchForBooks(string phrase)
    {
        return _db.Books.Include(x=> x.Images).LikeOr("Title", phrase).OrderBy(x => x.Title)
            .Take(6).Select(x => x).ToList()
            .OrderByCountDescending("Title", phrase);
    }

这是由Microsoft创建的动态LINQ dll实现的,但不包含在框架中。 Dynamic LINQ这将使您在某些方面更加灵活。