Я реорганизую проект MVC, чтобы сделать его проверяемым. В настоящее время контроллер использует объекты контекста Entity Framework напрямую, чтобы запросить требуемые данные. Я начал абстрактно это, и он просто не работает. В конце концов у меня есть IService и абстракция IRepository, но для описания проблемы давайте просто посмотрим на IRepository. Многие люди советуют интерфейс с функциями, которые возвращают некоторые из них: IQueriable < ...>, IEnumerable < ...>, IList < ...>, SomeEntityObject, SomeDTO. Затем, когда вы хотите протестировать сервисный уровень, они могут реализовать интерфейс с классом, который не переходит в базу данных, чтобы вернуть их.Проверка платформы Entity Framework с IRepository - проблема с ленивой загрузкой
Проблема: Использование linq для объектов У меня есть ленивый (отложенный) loading в моем наборе инструментов. Это действительно очень полезно, потому что мои функции управления контроллером знают, какие данные им нужны для представления, и я не просил больше, чем нужно. Однако linq to anythingelse не имеет ленивой загрузки. Поэтому, когда мои функции IRepository возвращают любую из вышеперечисленных вещей, я теряю ленивую загрузку. Я расширил свой интерфейс такими функциями, как «GetAnything» и «GetAnythingDeep», но этого недостаточно: он должен быть намного более мелким. Который привел бы к 5-6 функциям для одного и того же типа объекта, в зависимости от свойств, которые я хочу получить в результате. Возможно, это может быть общая функция с некоторым параметром «include properties», но мне это тоже не нравится.
В конце концов, я думаю, что если я хочу, чтобы это проверялось, что приведет к значительно менее эффективному или значительно более сложному коду. Звучит не так.
Btw Я думал о том, чтобы изменить источник данных по модели сущности для xml или некоторых данных объекта, и поэтому я мог бы поддерживать linq для объектов. Я обнаружил, что он не поддерживается из коробки ... что тоже печально: это означает, что сущность framework означает источник базы данных - не очень полезная абстракция.
Конкретный пример:
Entity объектов: Статья, Язык, Личность. Отношения: Статья может содержать 1-N языков и 1 Лицо (издатель).
ViewModel object: ArticleDeepViewModel: содержит все свойства статьи, включая языки и имя человека (это для просмотра статьи, поэтому нет необходимости в других свойствах человека).
Действие контроллера, которое вернет это представление, должно получить данные откуда-то.
Код Перед изменениями:
using (var context = new Entities.Articles())
{
var article = (from a in context.Articles.Include("Languages")
where a.ID == ID
select new ViewArticleViewModel()
{
ID = a.ID,
Headline = a.Headline,
Summary = a.Summary,
Body = a.Body,
CreatedBy = a.CreatedByEntity.Name,
CreatedDate = a.CreatedDate,
Languages = (from l in context.Languages select new ViewLanguagesViewModel() { ID = l.ID, Name = l.Name, Selected = a.Languages.Contains(l) })}).Single();
this.ViewData.Model = article;
}
return View();
код после модификации может быть что-то вроде:
var article = ArticleService.GetArticleDeep(ID);
var viewModel = /* mapping */
this.ViewData.Model = viewModel;
return View();
Проблема в том, что GetArticleDeep должен возвращать объект статьи с Языки включены и весь объект Person включено (его не должен знать, что в viewmodel требуется только Имя Лица). Кроме того, у меня есть 3 разных режима просмотра для статьи. Например, если кто-то хочет просмотреть список статей , тогда нет необходимости получать языки, тело и некоторые другие свойства, однако может оказаться полезным получить имя издателя (находящегося в глубине).До «проверяемого» кода действия контроллера могли просто содержать запрос linq к объектам и получать данные, которые им нужны, используя ленивую загрузку, Включить функцию, используя подзапросы, ссылаясь на внешние свойства (Publisher.Name) ... Таким образом, нет ненужного запрос к базе данных и отсутствие ненужных данных, переданных из базы данных.
Каким должен быть интерфейс IService или IRepository, чтобы получить 3-4 различных уровня объектов статьи или иногда список этих объектов?
Не могли бы вы опубликовать свой код: контроллер, репозиторий и объяснить, какую часть вы хотели бы модульного тестирования? –
под редакцией. я надеюсь, что это станет лучше, а не хуже :) – peterfoldi