实体框架高效查询(Entity Framework efficient querying)

2019-06-26 11:11发布

可以说,我有一个模型, Article具有大量列,并且该数据库包含超过10万行。 如果我这样做var articles = db.Articles.ToList()是检索数据库中的每一篇文章整篇文章模型并保持在内存中吗?

所以,如果我填充表只显示条目的日期,它的标题是有办法检索刚刚从这些使用实体框架的数据库列,这会更有效?

根据此 ,

有跟踪对象上下文中返回的对象所需的成本。 检测对象的更改,并确保为同一逻辑实体的多个请求返回相同的对象实例需要的对象附加到ObjectContext的实例。 如果你不打算进行更新或删除的对象,不需要身份管理,可以考虑使用NoTracking合并选项,当你执行查询。

它看起来像我应该使用NoTracking因为数据没有被修改或删除,才会显示。 所以我的查询现在变成var articles = db.Articles.AsNoTracking().ToList() 是否有其他的事情我应该做的,使这个更有效?

另一个问题我是根据这个答案 ,使用.Contains(...)与大型数据库打交道时,会引起较大的性能下降。 什么是使用大型数据库通过条目搜索推荐的方法?

Answer 1:

这就是所谓的投射 ,只是转换成一个SELECT column1, column2, ...在SQL:

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<T>.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();

这将转化成类似WHERE Body like N'%Entity Framework%'的SQL。 对表现不佳的答案Contains的并不适用于这个版本Contains在所有。



文章来源: Entity Framework efficient querying