简体   繁体   English

在实体框架中不使用Dispose或Using()

[英]Not Using Dispose or Using() in Entity Framework

I was writing a web app and learning entity framework along the way. 我一直在编写一个Web应用程序并学习实体框架。 I am curios if I have done something wrong though. 如果我做错了事,我很好奇。 I haven't been using dispose or using statements when querying. 查询时我没有使用过dispose或使用语句。

Example of a Repository of mine: 我的存储库示例:

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

My User table I selected from would have foreign keys which would be associated with other tables. 我从中选择的用户表将具有与其他表关联的外键。 The cool thing, or so I thought, about entity is that I could return the entire User object (built by entity) which then would allow me to do something like this User.MyOtherTable.SomeColumn in my controller. 我认为关于实体的最酷的事情是,我可以返回整个User对象(由实体构建),然后允许我在控制器中执行类似User.MyOtherTable.SomeColumn

The problem is I relied on this and went about my merry way in my controller of grabbing the user information as well as utilizing information from the other table. 问题是我依赖于此,并在我的控制器中以一种愉快的方式来获取用户信息以及利用来自其他表的信息。 I am now realizing that if I close that connection like the code below: 我现在意识到,如果像下面的代码那样关闭该连接:

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

My controller no long has access to User.MyOtherTable.SomeColumn as this will be null. 我的控制器不再有权访问User.MyOtherTable.SomeColumn因为它将为null。 My true question is how important is it for me use dispose in my entity application? 我真正的问题是,在实体应用程序中使用处置对我有多重要?

I would strongly recommend that you use using statements, and also that you stop relying on lazy-loading. 我强烈建议您使用using语句,并且也不要再依赖延迟加载了。

Instead of selecting User objects with lazy-load properties, work out the full data you need and project that to a Model class, eg 不用选择具有延迟加载属性的User对象,而是计算出所需的全部数据并将其投影到Model类,例如

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

Then in your method: 然后在您的方法中:

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;
    }
}

Not only does this mean you limit the number of database calls, but you have a data contract that isn't tied to your database model. 这不仅意味着您限制了数据库调用的次数,而且还拥有与数据库模型无关的数据协定。 If you move that column, you simply update the query to point to the new spot/name, the view can remain unchanged. 如果移动该列,则只需更新查询以指向新的地点/名称,视图就可以保持不变。

So when you dispose your context, you aren't going to be able to reference properties that are lazy loaded. 因此,在处置上下文时,将无法引用延迟加载的属性。 You'll need to make your context live longer either by having the context disposed when the controller is disposed (I don't remember if MVC does this per request or not) or by controlling the lifetime of the context using some attributes on the Action. 您需要通过释放控制器时释放上下文(我不记得MVC是否按请求执行此操作)或通过使用Action上的某些属性控制上下文的生存时间来延长上下文的生存时间。

Some examples on how to resolve this can be found in this question , which is pretty much the same as what you are asking here. 可以在此问题中找到一些有关如何解决此问题的示例,该示例与您在此处提出的要求几乎相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM