Объект не загружен из-за отложенной загрузки.Как вернуть все объекты из BLL - PullRequest
0 голосов
/ 22 января 2012

У меня возникли проблемы с поиском способа работы этого шаблона хранилища.

В двух словах, мое решение выглядит примерно так ...

        ASP.Net MVC
             ^
             |
       Business Logic
             ^
             |
       Data Access 
(Repositories and Unit of Work)
             ^
             |
  Entity Framework Models

Iу меня есть таблица Users со ссылкой на таблицу Roles.

В моем приложении MVC я вызываю BLL с помощью GetAllUsers.Код в 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,но когда я пытаюсь получить доступ к ссылке на роль, она еще не загружена из-за отложенной загрузки.

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

Я пытался поместить .Include (Roles) в GetAllUsers, но .Include isnнедоступно в IQueryable.

Теоретически, правильно ли я считаю, что приложению MVC не нужно ничего знать о контексте или доступе к данным?И во-вторых, как мне включить эту ссылку Роли в мой график, прежде чем он покинет BLL?

Ответы [ 2 ]

1 голос
/ 22 января 2012

Я сам был в таких ситуациях, когда вы хотите, чтобы код был «красивым и самодовольным», но абстракция не позволяет вам управлять базовой реализацией так, как вы хотите.

Сначала давайте зададим важный вопрос: какова вероятность того, что вы переключите используемое OR / M на другую реализацию?

Если это вполне вероятно, и вам действительно нужна абстракция, то это зависит от того, значительна ли производительность, которую вы теряете во всех отложенных выборках. Возможно, это не проблема? Тогда я буду в порядке с некоторыми N + 1 запросами.

Однако, если производительность не приемлема, вы можете попытаться добавить свой собственный интерфейс, который включает в себя Include методы по вашему собственному IQueryable. Хотя это немного уродливо, если вам нужна большая функциональность.

Чтобы обойти закрытый сеанс, вы можете либо перевести стиль жизни сеанса на более высокий уровень, либо использовать более конкретные методы, возвращая DTO. Тогда у вас не будет проблемы с незнанием того, что загружено, а что нет.

1 голос
/ 22 января 2012

Вы правы, считая, что ваше приложение MVC, учитывая текущую архитектуру приложения , не должно относиться к DataContext и поиску данных.

Возможно, решение состоит в том, чтобы добавить другоеRepository метод, который нетерпеливо загружает ваш Roles:

public IList<Users> GetAllUsersWithRoles()

Затем выборочно используйте подходящий метод, учитывая контекст.

...