博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
EntityFramework中的DbContext使用疑点说明
阅读量:4325 次
发布时间:2019-06-06

本文共 4181 字,大约阅读时间需要 13 分钟。

1.DbContext怎么在Asp.mvc中使用?

  public class Repository    {        //实例化EF容器:有弊端。一个线程里可能会创建多个DbContext        //DbContext db = new DbContext();        //改造:保证一个请求线程中只有一份EF容器(你要明白:一个url请求到服务器,IIS就开一个线程去处理)        protected DbContext GetDbContext        {            get            {                //向线程缓存中查询,如果返回的是null,则创建,同时存入到这个线程缓存中                //注意的是线程缓存CallContext,而不是我们熟悉的HttpRuntime.cache。意味着这个DbContext对象在这个线程内能被其他方法共享。                object efDbContext = CallContext.GetData("DbContext");                if (efDbContext == null)                {                    efDbContext = new DbContext();                    //存入到这个线程缓存中                    CallContext.SetData("DbContext", efDbContext);                }                return efDbContext as DbContext;            }        }  }

  这么定义之后,所有需要用到DbContext对象的地方,都调这个方法。

2. 不要随便using或Dispose DbContext会导致延迟加载的不可用,还会有一些其他错误 如IQueryable<T> 下面的方法(.First() /.Count())也不能用。

情况一:

  a写法结果正确

PhoneBookEntities phoneBookEntities = new PhoneBookEntities();var ci = phoneBookEntities.ContactInfo.FirstOrDefault();//这里并没有拿到ci对象里面的GroupInfo属性。if (ci != null) MessageBox.Show(ci.GroupInfo.GroupName);//是延迟加载,访问 ci.GroupInfo.GroupName 才会去数据库查数据

  b写法报错

ContactInfo ci = null;using (PhoneBookEntities phoneBookEntities = new PhoneBookEntities()){	ci = phoneBookEntities.ContactInfo.FirstOrDefault();}if (ci != null) MessageBox.Show(ci.GroupInfo.GroupName);//报错:此ObjectContext实例已释放,不可再用于需要连接的操作。意味着延迟加载不可用。

情况二:

  a写法报错

IQueryable
ci = null;using (PhoneBookEntities phoneBookEntities = new PhoneBookEntities()){ ci = phoneBookEntities.ContactInfo.Where(c => true);}if (ci != null) MessageBox.Show(ci.Count().ToString());//报错:提示DbContext已经释放。

  b写法正确

IQueryable
ci = null;using (PhoneBookEntities phoneBookEntities = new PhoneBookEntities()){ ci = phoneBookEntities.ContactInfo.Where(c => true); if (ci != null) MessageBox.Show(ci.Count().ToString());//可以返回正确结果。}

  

3.为什么你要using 或dispose掉DbContext ?

是担心数据库连接没有释放?还是担心DbContext占用过多资源呢?

首先担心数据库连接没有释放肯定是多余的,因为DbContext在SaveChanges完成后会释放掉打开的数据库连接。
可以反编译一下SaveChages的源码。
担心DbContext占用过多资源也是多余的,有GC回收。

结论,You can call Dispose, but in most common scenarios you don’t need to.

更详细的可以看这个英文博客的文章,其中有 :

Hello Jon,

The default behavior of DbContext is that the underlying connection is automatically opened any time is needed and closed when it is no longer needed. E.g. when you execute a query and iterate over query results using “foreach”, the call to IEnumerable<T>.GetEnumerator() will cause the connection to be opened, and when later there are no more results available, “foreach” will take care of calling Dispose on the enumerator, which will close the connection. In a similar way, a call to DbContext.SaveChanges() will open the connection before sending changes to the database and will close it before returning.

Given this default behavior, in many real-world cases it is harmless to leave the context without disposing it and just rely on garbage collection.

That said, there are two main reason our sample code tends to always use “using” or dispose the context in some other way:

1. The default automatic open/close behavior is relatively easy to override: you can assume control of when the connection is opened and closed by manually opening the connection. Once you start doing this in some part of your code, then forgetting to dipose the context becomes harmful, because you might be leaking open connections.

2. DbContext implements IDiposable following the recommended pattern, which includes exposing a virtual protected Dispose method that derived types can override if for example the need to aggregate other unmanaged resources into the lifetime of the context.

 

By the way, with DbContext the pattern to open the connection manually and override the automatic open/close behavior is a bit awkward:

((IObjectContextAdapter)dbContext).ObjectContext.Connection.Open()

But we have a bug to make this easier as it used to be with ObjectContext before, e.g.:

dbContext.Database.Connection.Open()

Hope this helps,

Diego

附上参考博客:http://www.cnblogs.com/mecity/archive/2011/07/17/2108508.html

 

转载于:https://www.cnblogs.com/ICE_Inspire/p/6159090.html

你可能感兴趣的文章
python的字符串内建函数
查看>>
Spring - DI
查看>>
微软自己的官网介绍 SSL 参数相关
查看>>
Composite UI Application Block (CAB) 概念和术语
查看>>
64位MATLAB和C混合编程以及联合调试
查看>>
原生js大总结二
查看>>
PHP基础
查看>>
UVa 11488 超级前缀集合(Trie的应用)
查看>>
Django 翻译与 LANGUAGE_CODE
查看>>
[转]iOS教程:SQLite的创建数据库,表,插入查看数据
查看>>
【转载】OmniGraffle (一)从工具栏开始
查看>>
初识ionic
查看>>
java 中打印调用栈
查看>>
开发 笔记
查看>>
数据挖掘算法比赛 - 简单经验总结
查看>>
生成商户订单号/退款单号
查看>>
使用Android OpenGL ES 2.0绘图之六:响应触摸事件
查看>>
我们过去几年做对了哪些事
查看>>
ubuntu 16.04LTS
查看>>
javascript深入理解js闭包
查看>>