由于延迟加载而未加载对象。如何从BLL返回所有对象

时间:2012-01-21 23:09:16

标签: linq asp.net-mvc-3 entity-framework repository-pattern unit-of-work

我在弄清楚如何使这个存储库模式工作时遇到了一些麻烦。

简而言之,我的解决方案看起来像这样......

        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之前,我应该如何在我的图表中包含此角色参考?

2 个答案:

答案 0 :(得分:1)

考虑到当前的应用程序架构认为你的MVC应用程序是正确的,不应该关注DataContext和数据检索。

解决方案可能是添加另一个急切加载Repository的{​​{1}}方法:

Roles

然后在给定上下文的情况下有选择地使用适当的方法。

答案 1 :(得分:1)

我自己一直处在这些情况下,你希望代码都“好看又好笑”,但是抽象并不能让你以你想要的方式控制底层实现。

首先,让我们提出一个重要问题:您将使用的OR / M切换到另一个实现的可能性有多大?

如果很可能,并且你真的需要抽象,那么它取决于你在所有延迟提取中丢失的性能是否显着。也许这不是问题?然后我就可以进行一些N + 1查询了。

但是,如果性能不可接受,您可以尝试添加自己的界面,其中包含您自己Include的{​​{1}}方法。如果你想要很多基础功能,那就会变得很丑陋。

要绕过关闭的会话,您可以将会话生活方式移至更高级别,或使用更具体的方法,返回DTO。那么你就不会有不知道什么是懒惰而不是什么的问题。