【问题标题】:Entity Framework efficient querying实体框架高效查询
【发布时间】:2012-07-21 12:06:08
【问题描述】:

假设我有一个模型,Article,它有大量的列并且数据库包含超过 100,000 行。如果我执行var articles = db.Articles.ToList() 之类的操作,它会为数据库中的每篇文章检索整个文章模型并将其保存在内存中,对吗?

因此,如果我正在填充一个仅显示条目日期及其标题的表,是否有一种方法可以仅使用实体框架从数据库中仅检索这些列,它会是效率更高?

根据this,

在对象中跟踪返回的对象需要成本 语境。检测对象的变化并确保多个 对相同逻辑实体的请求返回相同的对象实例 要求将对象附加到 ObjectContext 实例。如果你 不打算对对象进行更新或删除,并且不需要 身份管理时,请考虑使用 NoTracking 合并选项 你执行查询。

看起来我应该使用NoTracking,因为数据没有被更改或删除,只是显示。所以我的查询现在变成了var articles = db.Articles.AsNoTracking().ToList()。我还应该做些什么来提高效率吗?

我的另一个问题是,根据this answer,使用.Contains(...) 在处理大型数据库时会导致性能大幅下降。用于搜索大型数据库中的条目的推荐方法是什么?

【问题讨论】:

  • 顺便说一句:Contains 并不慢,因为数据库表很大。 Contains 询问:“给我具有 PropertyXValue = 1 OR PropertyXValue = 5 OR PropertyXValue = 7 等的实体。”Contains 如果收集这些“OR 值”会很慢“你要求的很大。那么对于一张小桌子,即使是一张空桌子,它也很慢。

标签: sql-server entity-framework linq-to-sql


【解决方案1】:

它被称为 投影,在 SQL 中只是转换为 SELECT column1, column2, ...:

var result = db.Articles
    .Select(a => new
    {
        Date = a.Date,
        Title = a.Title
    })
    .ToList();

除了a => new { ... }(创建“匿名”对象列表),您还可以使用命名的帮助器类(或“视图模型”):a => new MyViewModel { ... },它仅包含选定的属性(但您不能使用a => new Article { ... } 作为实体本身)。

对于这样的投影,您不需要AsNoTracking(),因为无论如何都不会跟踪投影数据,只会跟踪完整的实体对象。

而不是使用Contains,更常见的方法是使用Where,例如:

var date = DateTime.Now.AddYears(-1);
var result = db.Articles
    .Where(a => date <= a.Date)
    .Select(a => new
    {
        Date = a.Date,
        Title = a.Title
    })
    .ToList();

这将只选择不超过一年的文章。 Where 只是被翻译成 SQL WHERE 语句并在数据库中执行过滤(这与 SQL 查询一样快,取决于表大小和适当的索引等)。只有这个过滤器的结果被加载到内存中。

编辑

参考您的评论如下:

不要将IEnumerable&lt;T&gt;.Contains(T t) 与string.Contains(string subString) 混淆。您在问题中链接的答案是关于Contains 的第一个版本。如果要搜索正文中包含字符串"keyword" 的文章,则需要第二个Contains 版本:

string keyword = "Entity Framework";
var result = db.Articles
    .Where(a => a.Body.Contains(keyword))
    .Select(a => new
    {
        Date = a.Date,
        Title = a.Title
    })
    .ToList();

这将在 SQL 中转换为类似于 WHERE Body like N'%Entity Framework%' 的内容。关于Contains 性能不佳的答案根本不适用于这个版本的Contains。

【讨论】:

  • 我在大多数情况下使用Where,但是在查找正文中包含“关键字”的文章时,.Contains 是最佳搜索方式吗?同样在您的示例中,您有.Where(a =&gt; date &lt;= a.Date) 不应该是.Where(a =&gt; a.Date &gt;= date) 还是有关系?
  • @GarrettFogerlie:关于Contains,请参阅上面的编辑。但是,如果您有很多关键字查询,“全文搜索”功能可能是更好的解决方案。对于date &lt;= a.Date 或a.Date &gt;= date,没关系,它会产生相同的结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-30
  • 2019-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
  • 2013-03-17
相关资源
最近更新 更多