【问题标题】:how to speed up query binary search in LINQ如何在 LINQ 中加快查询二进制搜索
【发布时间】:2014-02-23 07:29:47
【问题描述】:

我使用 Linq select 语句从数据库中获取文件作为字节。从我的文件表中获取字节数组需要很长时间。

我正在使用此代码:

Fun<Files,bool> Filter  = delegate(Files x)
{
     return x.FileID == 10;
}; 
Files File = DAL.FilesDAL.GetFile(Filter).First();


public static List<Files> GetFile(Func<Files,bool> lambda){
return db.Where(lamnda).ToList();
}

对于 1M 的文件大小,最多需要 1m。这对我的客户来说太长了。

如何提高查询的速度?

【问题讨论】:

  • 您向我们展示的代码不是查询...展示您如何使用您在此处声明的Filter
  • 好的,我们还有更多内容。现在,GetFile 是如何定义的?
  • 知道 MarcinJuraszek 吗?

标签: c# asp.net sql linq


【解决方案1】:

看起来您错过了这样一个事实,即使用 Func&lt;&gt; 会使您的查询作为 LINQ to Objects 执行。这意味着整个表被提取到应用程序内存中,然后由应用程序执行过滤,而不是由数据库执行。为了使过滤器在数据库中执行,它应该作为Expression&lt;Func&lt;&gt;&gt; 传递:

public static List<Files> GetFile(Expression<Func<Files,bool>> lambda){
    return db.Where(lamnda).ToList();
}

我假设这里的dbIQueryable&lt;Files&gt;

调用它使用:

Files File = DAL.FilesDAL.GetFile(x => x.Filter == 10).First();

为了使其更具描述性,您可能应该将方法更改为只返回一个Files 项目。方法名称是GetFile,所以我希望它返回一个文件,而不是文件集合:

public static Files GetFile(Expression<Func<Files,bool>> lambda){
    return db.FirstOrDefault(lamnda);
}

用法:

var File = DAL.FilesDAL.GetFile(x => x.Filter == 10);

或者为了增加语义,可以将方法重构为GetFileById,取Id,而不是表达式:

public static Files GetFileById(int Id)
{
    return db.FirstOrDefault(x => x.FileId == id);
}

用法

var File = DAL.FilesDAL.GetFileById(10);

【讨论】:

  • 非常感谢 MarcinJuraszek ...它对我有用。现在速度不错。
【解决方案2】:

如何提高查询的速度?

更快的服务器。更快的网络。不要获取你不需要的二进制内容。

这样简单。您在 LINQ 级别上做的任何事情都无法神奇地修复糟糕的设计。

一般:

顺便说一句,一个严重的错误 - 您在 GetFiles 中返回 ToList。永远不要那样做。要么让它成为可查询的,这样用户就可以添加条件和顺序和分组,或者返回一个可枚举的对象(功能不那么强大),但 ToList 意味着所有内容都进入内存 - 即使用户随后不想要列表。

伙计,提交 lambdaa 的方式是多余的和限制性的。糟糕的设计。

【讨论】:

  • ToList() 与返回 IEnumerable&lt;&gt; 没有什么不同——两者迟早都会在应用程序内存的某个地方实现集合。但是项目的数量将是相同的。这并不总是一件坏事,只要您只获取并实现必要的项目,而不是整个表。
  • IEnumerable 单独不会具体化查询。 MyEnumerable.Any() 将获取一条记录,但 MyList.Any() 获取之前的所有记录(以获取列表)。
  • 这就是整个想法。留给用户决定,这样他就可以添加诸如分组依据之类的东西。除非需要,否则不应实现查询。破损的设计。
  • @alzaimar Any() on IEnumerable() 仍会将所有数据带入内存,因为 Any 将作为 LINQ to Objects 查询执行,而不是作为 EF/LINQ to SQL/anyOtherORMQuery 执行。要使 Any 在 DB 上执行,您必须从 DAL 中公开 IQueryable
  • 正确。我把它弄混了。
猜你喜欢
  • 1970-01-01
  • 2012-05-01
  • 2014-02-15
  • 1970-01-01
  • 1970-01-01
  • 2013-03-17
  • 1970-01-01
  • 2011-11-21
  • 1970-01-01
相关资源
最近更新 更多