Я попытаюсь описать проблему, которую я вижу очень часто на своем рабочем месте, но я не мог найти способ или разумное решение. Я много искал об этом, и все, что я смог найти, это то, что я уже реализовал. Сценарий таков:ASP.NET MVC + Entity Framework - Как работать с DTO и ViewModel's
У меня есть приложение ASP.NET MVC, использующее Entity Framework, которое следует за шаблоном репозитория. Я буду использовать простой студент/структуру базы данных Преподаватель иллюстрировать
Entities
public class Student : BaseEntity
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public Teacher Tutor { get; set; }
}
public class Teacher : BaseEntity
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Student> Students { get; set; }
}
public class BaseEntity
{
public byte State { get; set; }
public Datetime CreateDate { get; set; }
public Datetime UpdateDate { get; set; }
}
Теперь, скажем, мне нужно выставить метод возвращает список имен студентов вместе с именем своего учителя:
var students = context.Students.Include(x => x.Teacher).ToList();
Вышеприведенный запрос является плохим, и все мы это знаем, так как он возвращает все столбцы. Теперь, если мы реорганизуем на это:
var students = context.Students.Include(x => x.Teacher)
.Select(x => new
{
Name = x.Name,
TeacherName = x.Teacher.Name
}).ToList();
У меня будет запрос на выполнение, который выбирает только те поля, которые я хочу. Это хорошо. Но теперь мне нужно сделать выбор. Чтобы вернуть этот список моему контроллеру, я могу либо: создать StudentDTO, либо заполнить экземпляр Student только столбцами, которые я выбрал в своем запросе.
DTO подход
Если я создаю DTO и передать его на мой контроллер все будет «отлично». Не беспокойтесь о лишних ненужных полях.
Вернуться EF Entity Student
Если я возвращаю объект базы данных на мой контроллер, как есть, даже если я загрузил его только поля, которые я хотел, я получу все остальные пустые поля. Поэтому я создаю ViewModel для возврата только тех данных, которые я хочу. (Это то, что мы делаем сейчас в большинстве методов наряду с AutoMapper)
Проблема:
Смотрите рисунок? В любом случае, я закончил создание класса для отображения моего возвращения. Я в порядке с этим большую часть времени, но в проекте, над которым я сейчас работаю, у нас есть несколько способов разоблачения, и каждый из них имеет другую структуру возврата. Например, что, если я хочу вернуть список студентов, который содержит только идентификатор и имя ученика? Создать еще один DTO или ViewModel?
В проекте есть команда из 5 разработчиков, а папка ViewModel становится наполненной классами. Я начал инструктировать, чтобы они возвращали анонимный объект внутри контроллера, когда возвращаемый метод очень специфичен. Я только создаю Модели для просмотра сейчас, когда я уверен, что их можно повторно использовать в другом месте.
Но этот анонимный подход стал также плохим, потому что теперь я должен делать это в нескольких контроллерах, и я чувствую, что повторяюсь.
Есть ли другой подход, который я могу использовать для решения этой проблемы? Конечно, проект, о котором я говорю, намного сложнее, чем этот пример, с несколькими объектами и довольно сложными запросами. Я чувствую, что это происходит в других проектах, и я не смог найти достойный выход из этого.
Почему подход DTO с пустыми полями не в порядке? –
С DTO у меня не будет пустых полей. Если я верну свой объект базы данных, я получу пустые поля. См. Базовый класс? Мне не нужно государство и другие вещи на моей стороне клиента. Проблема в том, что я считаю очень неэффективным продолжать создавать новые классы (DTO или ViewModel) каждый раз, когда мне нужно возвращать данные по-другому. – jpgrassi