【问题标题】:EF - Getting metadata about related entities by eager loading to avoid extra DB callsEF - 通过预先加载获取有关相关实体的元数据以避免额外的数据库调用
【发布时间】:2013-08-26 17:28:06
【问题描述】:

场景:

  1. 我有用户。每个用户都可以是文章的“作者”。 (一篇文章可以有多个合作的“作者”。)

  2. 我想提供一个 GUI 界面来按名称搜索用户。您将看到一个列表,其中有任何文章的作者都有指向其文章的链接,而那些为 0 的作者仍然会显示但没有链接。

实施:

  1. 我为客户端提供了一个搜索界面。他们将搜索字符串发送到我的 UserSearchForArticlesList 控制器,在那里我向 EF 询问名称与搜索查询匹配的所有用户,并将此列表发送到我的视图。

  2. 视图遍历用户列表。对于每个它检查它是否有任何公开的文档(用户文章的连接表,我知道 EF 可以在不使其可见的情况下解决这个问题,但现在就是这样。)如果用户与公共文章有连接,它会创建一个 ActionLink,统计公开文章并通过链接显示此计数。

控制器(无需在视图中预先加载所需数据):

[HttpGet]
public ActionResult UserSearchForArticlesList(string searchTerm)
{
    var model = myEF.Users.Where(x => x.Name.Contains(searchTerm)).OrderBy(x => x.Name).ToList();
    return View("Index", model);
}

查看:

 @foreach (var item in Model)
    {
        if (item.UserArticles.Any(o => o.Article.IsPublic))
        {
            <li>@Html.RouteLink(item.Name, "UserArticles", new { item.Id }) (@item.UserArticles.Count(o => o.Article.IsPublic))</li>
        }else
        {
            <li title="No public articles for this User">@item.Name</li>
        }
    }

问题:

通过延迟加载用户的关系,我会为列表中的每个用户收到多个调用。当我急切加载 (.Inlude(user => user.UserArticles.Articles)) 时,我只接到一个电话,但是我确实需要大量数据。

您是否有可能以某种方式让 EF 仅使用合理数量的 DB 调用来获取匹配的用户以及该用户的已连接公共文章的计数?

“刚刚写了一篇关于我的问题的大文章”-insight:

实际上只是在调试和查看 EF 分析器时发现,if 子句和视图中的计数都会导致对数据库的大量单行查询。为什么是这样? EF 不应该为此找出一些缩小的 SQL 查询吗?

更新:

我显然没有足够的 EF 经验来就此提出一个明智的问题。我上面的帖子中的一个问题是我在视图中迭代它之前没有枚举 IQueryable,因此它会为每个步骤发出一个 SQL 请求。不过,主要问题仍然存在。

【问题讨论】:

  • 这就是我渴望加载关系的方式: var model = myEF.Users.Include(user => user.UserArticles.Article).Where(x => x.Name.Contains (searchTerm)).OrderBy(x => x.Name)}; ,但正如我所说,这就是需要大量数据的方式。

标签: c# asp.net-mvc entity-framework linq-to-entities


【解决方案1】:

有两种方法可以禁用 LazyLoading。

第一种方式,使用属性myEF.Configuration.LazyLoadingEnabled = false;

第二种方式,在没有虚拟世界的情况下使用 UserArticles 列表。

public class User 
{ 
    public ICollection<UserArticle> UserArticles { get; set; } 
}

【讨论】:

  • 我对延迟加载本身的禁用没有任何问题,我只包含我想要的相关属性,但问题仍然是在这种情况下我获得了我需要的大量数据.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-29
  • 2021-08-18
  • 2012-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-07
相关资源
最近更新 更多