2008-09-09 2 views
11

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

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

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

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

+0

Я разместил ссылки на внешнее сопоставление XML здесь: http://stackoverflow.com/questions/988872/linq-to-sql-external-mapping/1136039#1136039 – alexandrul 2009-07-16 07:58:29

ответ

5

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

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

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

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

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

+4

Я рекомендую точную противоположность. Я бы никогда не вернул IQuerable над IList вне DAL. Если вы это сделаете, то ваш уровень представления, скорее всего, закончит выполнение запросов к базе данных непреднамеренно, или вы можете в конечном итоге смешать вызовы Linq-to-objects и получить ошибку Linq-to-sql. Возвращение IQuerable из Linq-to-sql делает очень плохую и негерметичную архитектуру, и ее следует избегать для всех, кроме самых маленьких игрушечных приложений. – mattmc3 2010-10-12 01:52:49

2

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

+0

Согласовано. По сути, ваши объекты Linq-to-sql можно рассматривать как DTO, и есть даже шаблон T4 для генерации ваших объектов L2S как сериализуемых. – mattmc3 2010-10-12 01:54:22

Смежные вопросы