c# - 如何在 Entity Framework 6 中延迟加载关系?

标签 c# asp.net-mvc entity-framework lazy-loading eager-loading

我有一个使用 Entity Framework 6 和 ASP.NET MVC 5 的项目。

我需要使用延迟加载而不是急切。换句话说,我希望能够在不使用 .Include()

检索父模型后访问关系/子模型

这是我的简单用例

public ActionResult Test(int id)
{
    using(var conn = new MyAppContent())
    {
        var user = conn.User.Where(u => u.Id == id).First();

        var capsule = new SomeWrapper(user)

        return View(capsule);
   }
}

简而言之,这是我的 SomeWrapper 类。 (为了简单起见,我删除了大部分代码。)

public SomeWrapper
{
    public User MyUser { get; set; }
    public SomeWrapper(User user)
    {
        MyUser = user;
    }
    // Of course this class does more than this.
}

这是我的用户模型

public User
{
    public int Id { get; set; }
    public string Username { get; set; }

    [ForeignKey("TimeZone")]
    public int? TimeZoneId { get; set; }
}

现在我想从 View 中知道用户的时区。所以我做了这样的事情

@model App.SomeWrapper
<p>Model.MyUser.Username<p>
<p>Model.MyUser.TimeZone.Name<p>

但是,当尝试访问 TimeZone.Name 时出现以下错误

{"The ObjectContext instance has been disposed and can no longer be used for operations that require a connection."}

我不确定它是如何处理的?我在 using(){} block 中返回 View()。所以它应该在我访问它之后被处理掉。

我可以切换到预先加载“下面的代码”来解决问题,但我想知道如何使用延迟加载来做同样的事情。

public ActionResult Test(int id)
{
    using(var conn = new MyAppContent())
    {
        var user = conn.User.Where(u => u.Id == id).Include(x => x.TimeZone).First();

        var capsule = new SomeWrapper(user)

        return View(capsule);
   }
}

如何正确延迟加载 TimeZone 关系?

最佳答案

您不应在 SomeWrapper 中访问 MyUser.TimeZone

您在那里所做的是浅拷贝 User 到 MyUser,并混合域模型 (有些称为实体模型) View 模型。这不是一个好的做法,因为领域模型永远不应该暴露给公众。

您不应从域模型浅复制到 View 模型。相反,您需要使用对象-对象映射器进行深度复制,例如 AutoMapper .

延迟加载

Entity Framework 已经提供延迟加载,但您不能在检索数据后立即释放 DbContext

相反,您需要使用 IoC 容器(例如 Autofac、Ninject)注入(inject) MyAppContent。

例如,

public class MyController : Controller
{
    private readonly MyAppContent _myAppContent;

    public MyController(MyAppContent myAppContent)
    {
        _myAppContent = myAppContent;
    }

    public ActionResult Test(int id)
    {
        var user = _myAppContent.User.Where(u => u.Id == id).First();

        ...
    }
}

关于c# - 如何在 Entity Framework 6 中延迟加载关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43213764/

相关文章:

c# - Using block 中的异步

asp.net-mvc - Entity Framework MVC Controller

javascript - jQuery 中的 Bootstrap 菜单单击事件

c# - 如何识别标记为级联删除的关联

c# - 在 ASP.NET Core Web 应用程序中,AddJsonOptions 和 AddJsonFormatters 之间有什么区别?

c# - 为什么这个方法需要递归?

c# - itextsharp pdf页面边框?

c# - 如何通过asp.net mvc c#获取浏览网站的客户端mac地址

entity-framework - 如何在 .NETCore 3.1 和 Blazor 中创建 DbContextFactory

entity-framework - 在 ViewBag 中填充匿名类型会导致模型绑定(bind)器问题