【问题标题】:Populating a Lazy<T> collection填充 Lazy<T> 集合
【发布时间】:2015-11-02 13:34:33
【问题描述】:

我正在尝试解决 ASP.Net MVC 应用程序中的延迟加载问题。例如,我有一个类,其属性是一个集合(Employees)。我希望仅在需要加载集合时才加载:

public class Department
{
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int DepartmentId { get; set; }
    public string DepartmentName { get; set; }

    [ForeignKey("DepartmentId")]
    public Lazy<ICollection<Employee>> Employees { get; set; }
}

首先,我不确定是否应该延迟加载类或集合

    public Lazy<ICollection<Employee>> Employees { get; set; }
    public ICollection<Lazy<Employee>> Employees { get; set; }

我假设收藏。

接下来,我似乎找不到相关示例来实际加载属性/集合,一旦我需要它并且在类被实例化之后。我也不确定这是在类本身还是在我的 MVC 控制器中完成的。

感谢任何帮助。

【问题讨论】:

  • 有很多例子 - 当你创建一个新的 Lazy 时,你在它的构造函数中传递了 ghe 工厂方法。只有在请求 Lazy 的值时才会调用工厂。仅仅声明一个 Lazy 属性并不意味着任何东西都会被延迟评估。
  • 部门类是 EF 模型的一部分吗?在这种情况下,您不需要声明集合惰性
  • 顺便说一句,您是否将延迟加载(ORM 概念)与无关的延迟评估概念(Lazy 是关于什么)混为一谈? 关系默认是延迟加载的——你必须使用Include()调用来急切地加载相关对象。
  • 它是 EF 代码优先。有很多例子,但我可能无法破译它们并将它们应用到我的例子中。
  • 我可能混淆了概念。基本上,如果我将员工集合设置为虚拟,我将获取每个部门的所有员工。当我打电话给班级时。当我想向所有员工展示一次离职时,这只是一个好主意。另一方面,当我在员工视图上有一个部门下拉列表时,我不想在实例化此类时为每个离职加载每个员工。希望这是有道理的。

标签: asp.net-mvc entity-framework collections lazy-loading


【解决方案1】:

您不必在 Employees 属性上使用 Lazy&lt;T&gt;。您只会添加不必要的“惰性”,因为实体框架(和其他 ORM,如 NHibernate)查询已经是惰性的,即:查询只会在您明确告诉它时访问数据库。

所以,通过将Employees 设为:

public virtual ICollection&lt;Employee&gt; Employees { get; set; } //make sure to mark it as virtual, otherwise it won't be lazy

查询时:

var result = myContextObj.Departments.Include(d=&gt; d.Employees).Where(d=&gt; d.Id == someID).SelectMany(d=&gt; d.Employees);

上面的代码什么都不做,只是创建了一个查询对象,表示可以发送到数据库的查询。但它不会做任何事情,除非你“实现”结果,或者通过在@987654327 上执行foreach @,或者打电话给ToList()

【讨论】:

  • 谢谢,我明白了。
【解决方案2】:

对于延迟加载,您必须:

  • public virtual ICollection&lt;Lazy&lt;Employee&gt;&gt; Employees { get; set; }。您实际上错过了virtual,它允许框架通过覆盖属性来创建代理;
  • context.Configuration.ProxyCreationEnabled = true;,这是默认值。

【讨论】:

  • 实际上,当我重读这篇文章时,我想我可能明白发生了什么:stackoverflow.com/questions/11469432/… 当我将属性最初设置为虚拟属性(而不是 Lazy)并进行调试时,我实际上是在访问该属性,从而加载它。这让我陷入了困境。因此,如果我只是将其设置回“public virtual ICollection Employees { get; set; } 它应该只在访问集合时加载,对吧?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 2023-03-23
  • 2010-11-27
  • 2012-03-02
  • 1970-01-01
  • 1970-01-01
  • 2016-12-10
相关资源
最近更新 更多