【问题标题】:Not Using Dispose or Using() in Entity Framework在实体框架中不使用 Dispose 或 Using()
【发布时间】:2014-01-23 12:48:24
【问题描述】:

在此过程中,我正在编写一个 Web 应用程序和学习实体框架。如果我做错了什么,我很好奇。查询时我没有使用 dispose 或 using 语句。

我的存储库示例:

public User GetUserById(int sessionId)
{
    var user = (from u in db.Users where u.Id == sessionId select u).SingleOrDefault();
    return user;
}

我从中选择的用户表将具有与其他表相关联的外键。很酷的事情,或者我认为,关于实体是我可以返回整个用户对象(由实体构建),然后我可以在我的控制器中执行类似 User.MyOtherTable.SomeColumn 的操作。

问题是我依靠这个并在我的控制器中以我的快乐方式获取用户信息以及利用来自另一个表的信息。我现在意识到,如果我像下面的代码那样关闭该连接:

public User GetUserById(int sessionId)
{   using(db)
    {
    var user = (from u in db.Users where u.Id == sessionId select u).SingleOrDefault();
    return user;
    }
}

我的控制器无法再访问User.MyOtherTable.SomeColumn,因为这将为空。我真正的问题是,在我的实体应用程序中使用 dispose 对我来说有多重要?

【问题讨论】:

    标签: c# asp.net-mvc entity-framework dispose


    【解决方案1】:

    我强烈建议您使用 using 语句,并停止依赖延迟加载。

    不要选择具有延迟加载属性的 User 对象,而是计算出您需要的全部数据并将其投影到模型类,例如

    public class UserWithOtherStuffModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string OtherStuff { get; set; }
    }
    

    然后在你的方法中:

    public UserWithOtherStuffModel GetUserById(int sessionId)
    {
        using(db)
        {
            var user = (from u in db.Users 
                where u.Id == sessionId 
                select new UserWithOtherStuffModel{
                    Id = u.Id,
                    Name = u.Name,
                    OtherStuff = u.MyOtherTable.SomeColumn
                }).SingleOrDefault();
            return user;
        }
    }
    

    这不仅意味着您限制了数据库调用的次数,而且您拥有一个与您的数据库模型无关的数据契约。如果移动该列,只需更新查询以指向新的地点/名称,视图可以保持不变。

    【讨论】:

    • 我不同意using的说法。但仅在上下文中。在这种情况下,OP 指的是MVC,我认为这意味着他在Controller 中执行此操作。 Controller : IDisposible 因此,您应该在构造函数中实例化上下文,然后在 dispose 覆盖中处理它。将生命周期留给实际调用代码中的using 定义(MVC 框架)。
    • @Aron 公平点,但它会为那些长期不这样做的人造成坏习惯(因此不知道它在哪里,并且不可以离开 @987654329 @ 语句)并使其对于查看代码的初级编码人员来说不太明显。一方面我同意并且在这种情况下更喜欢这种方式,另一方面我看到它可能造成的混乱。
    • 我的一般规则是这样的。要么使用using,要么如果调用代码是一次性的,那么你可以将生命周期链接到调用类而不是using(假设某处有一个附加的使用)。
    • @Aron 假设您希望在保留一次性类的情况下保留数据库锁,那么这确实有效,所以在此要小心。 Controller 类是一个应该非常安全的地方,但其他一次性类的寿命可能比您预期的要长。我原则上同意你的看法。
    【解决方案2】:

    因此,当您处置上下文时,您将无法引用延迟加载的属性。您需要通过在释放控制器时释放上下文(我不记得 MVC 是否按请求执行此操作)或通过使用 Action 上的某些属性控制上下文的生命周期来延长上下文的寿命.

    一些examples on how to resolve this can be found in this question,和你在这里问的差不多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-05
      • 1970-01-01
      • 2014-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-16
      相关资源
      最近更新 更多