Разделение проблем с Linq To SQL и DTO

Недавно я начал новый проект webforms и решил отделить бизнес-классы от любых ссылок DBML. Мои классы бизнес-уровня вместо этого обращаются к дискретным методам уровня данных и возвращаются коллекциями DTO. Таким образом, слой данных может проектировать DTO следующим образом:

(from c in dataContext.Customers
where c.Active == true 
select new DTO.Customer
{
   CustomerID = c.CustomerID,
   Name = c.CustomerName,
   ...
}).ToList()

Хотя создание объектов DTO добавляет работу, это похоже на лучший подход к жесткой привязке между уровнями Business and Data и означает, что я могу тестировать уровень Business без присутствия базы данных.

Мой вопрос в том, является ли это хорошей практикой? Есть ли способ генерации DTO (может быть, через SQLMetal) и какие другие проблемы могут возникать при продвижении проекта.

Ответ 1

Я не знаю, была ли это лучшей практикой, но я написал такой код в недавнем прошлом, потому что я тоже чувствовал, что могу улучшить разделение проблем, используя свои собственные классы вместо созданных LINQ-конструкторов в моем приложении.

Возможно, вам захочется рассмотреть возможность возврата IQueryable <Customer> вместо IList <Customer> от вашего метода доступа к данным. Поскольку IQueryable <T> наследует от IEnumerable <T> остальная часть вашего приложения должна иметь возможность справиться с этим достаточно хорошо. Вы также можете преобразовать его в список, когда вам действительно нужно.

Преимущество этого заключается в том, что вы можете легко модифицировать свой запрос динамически и минимизировать количество данных, возвращаемых с SQL Server.

например. если ваша подпись метода IQueryable < Клиент > GetCustomers() вы можете получить одного клиента, вызвав GetCustomers(). Где (c = > c.CustomerID == 101).Single();

В этом примере из базы данных будет возвращена только одна запись, тогда как я предполагаю, что в настоящее время ваш код будет возвращать либо всех клиентов, либо вам придется писать отдельные методы (и, следовательно, очень повторяющийся код), чтобы обслуживать все разные вещи вы можете фильтровать.

Ответ 2

По моему мнению, в большинстве случаев объекты DTO не нужны при работе с LINQ. Сгенерированные классы LINQ можно легко протестировать. LINQ дает вам возможность запрашивать ваши данные из разных источников, используя идентичные запросы. Это дает вам возможность тестировать ваши запросы против списков объектов вместо реального db.