我在弄清楚如何使这个存储库模式工作时遇到了一些麻烦。
简而言之,我的解决方案看起来像这样......
ASP.Net MVC
^
|
Business Logic
^
|
Data Access
(Repositories and Unit of Work)
^
|
Entity Framework Models
我有一个带有对Roles表的引用的Users表。
在我的MVC应用程序中,我使用GetAllUsers调用BLL。 BLL中的代码如下所示:
public List<User> GetAllUsers()
{
using (UnitOfWork uow = new UnitOfWork())
{
UserRepository userRepository = new UserRepository(uow);
return userRepository.GetAll().ToList();
}
}
UserRepository派生自GenericRepository,它具有GetAll()
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
private IUnitOfWork _uow = null;
public GenericRepository(IUnitOfWork uow)
{
_uow = uow;
}
public virtual IQueryable<T> GetAll()
{
return _uow.Set<T>().AsQueryable();
}
}
它会向我的MVC应用程序返回一个用户列表,但是当我尝试访问Role引用时,由于延迟加载,它尚未加载。
public ActionResult Index()
{
BusinessLogic.Account blAcct = new BusinessLogic.Account();
List<User> users = blAcct.GetAllUsers();
string firstName = users.FirstName; // Works fine
string role = users.Roles.RoleName; // Fails because the context is closed.
return View();
}
我试图在GetAllUsers上添加.Include(角色),但IQIeryable上没有.Include。
从理论上讲,我是否认为MVC应用程序不需要了解有关上下文或数据访问的任何内容? 其次,在离开BLL之前,我应该如何在我的图表中包含此角色参考?
答案 0 :(得分:1)
考虑到当前的应用程序架构,认为你的MVC应用程序是正确的,不应该关注DataContext
和数据检索。
解决方案可能是添加另一个急切加载Repository
的{{1}}方法:
Roles
然后在给定上下文的情况下有选择地使用适当的方法。
答案 1 :(得分:1)
我自己一直处在这些情况下,你希望代码都“好看又好笑”,但是抽象并不能让你以你想要的方式控制底层实现。
首先,让我们提出一个重要问题:您将使用的OR / M切换到另一个实现的可能性有多大?
如果很可能,并且你真的需要抽象,那么它取决于你在所有延迟提取中丢失的性能是否显着。也许这不是问题?然后我就可以进行一些N + 1查询了。
但是,如果性能不可接受,您可以尝试添加自己的界面,其中包含您自己Include
的{{1}}方法。如果你想要很多基础功能,那就会变得很丑陋。
要绕过关闭的会话,您可以将会话生活方式移至更高级别,或使用更具体的方法,返回DTO。那么你就不会有不知道什么是懒惰而不是什么的问题。