UI 界面
BLL 业务
DAL DBContext放在这层中
Mode 实体用EF的CodeFirst方式建立实体
问题1:
通常在DAL中操作时,比如查询一个实体
using(var db = new ..DBcontext())
{
return db.Users.FirstOrDefault();
}
这样当查询得到的这个User到达BLL层或者UI层的时候就失去了延迟加载的功能,因为DBContext被释放了,比如在BLL层去访问User.Role.Name 就会爆异常了。
这种问题该怎么处理呢?如果不用using释放DBContext,那不是会出现很多很多DBContext的实例么?
问题2:
接上问,有博友说尽量让一次请求保持一个DBContext的实例。那会不会造成这个实例Savechanges()的时候把里面说有挂起的事务都提交了?不会出问题么?另外我个人觉得应该把DBCotext放在BLL层,然后每做一个操作就创建一个DBContext,然后使用完毕之后就销毁(一般就using),这样利用了DBContext本身提供的事务功能,也杜绝了一个SaveChanges()把其它还没准备好的事务也提交了。不知道我这样做是否合理。
请有经验的朋友指点下,实在困惑
使用延迟加载(Lazy Loading)的确存在这个问题,而且一不小心就会成为性能杀手,所以我们在开发中就不用EF的延迟加载功能。
大哥有EF在分层架构中应用的例子或者文章么?
@jionsoft: 建议了解一下基于DDD的n层架构,推荐知识库中的文章:http://kb.cnblogs.com/tag/ddd/
是啊 ,看起来很好,
之前看过大神陈晴阳写的DDD的帖子,其中将DbContext注入到应用层,这样可以做到针对用例来实例化数据库上下文对象。
如果这样的话,那说明DBContext应该在BLL层中创建,然后注入到DAL层中,在我的印象中 DDD的Services层+领域模型层 对应的就是BLL层。
1、关于延迟加载的问题,如果是在bll中直接把实体类传递给UI层,那么此时就需要保证dbcontext不能释放,这个时候可以跟nh那种做法就是在请求的时候创建一个dbcontext,然后保存在当前请求中,请求结束就释放掉,还有一种是bll是把实体类转换成dto传递给UI层的,这个情况的话不会用到延迟加载(当然是需要延迟加载的,不过都在bll里面)
这样是不是限定只能用EF了