2008-09-09 8 views
11

Recientemente comencé un nuevo proyecto de formularios web y decidí separar las clases de negocios de cualquier referencia de DBML. Mis clases de capas de negocios en cambio acceden a métodos discretos de capa de datos y son colecciones devueltas de DTO. Por lo que la capa de datos podría proyectar DTO como la siguiente:Preocupaciones de separación con Linq To SQL y DTO

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

Aunque la construcción de los objetos DTO añade el trabajo, esto se siente como una mejor aproximación a una unión estrecha entre el negocio & capas de datos y significa que puedo probar la capa de negocios sin una base de datos presente.

Mi pregunta es, ¿esta es una buena práctica ?, ¿hay alguna forma de generar los DTO (tal vez a través de SQLMetal) y qué otros problemas podría tener a medida que avanza el proyecto?

+0

He publicado algunos enlaces sobre mapeo XML externo aquí: http://stackoverflow.com/questions/988872/linq-to-sql-external-mapping/1136039#1136039 – alexandrul

Respuesta

5

No sé si es la mejor práctica pero he escrito un código similar en el pasado no tan reciente porque también sentí que podía mejorar la separación de las preocupaciones al usar mis propias clases en lugar del LINQ-designer-generated unos dentro de mi aplicación.

Es posible que desee considerar que acaban de volver de un cliente IQueryable < > en lugar de un cliente IList < > de su método de acceso a datos. Desde IQueryable <T> hereda de IEnumerable <T> el resto de su aplicación debería ser capaz de manejarlo bastante bien. También puede convertirlo en una lista cuando realmente lo necesite.

La ventaja de esto es que puede modificar dinámicamente su consulta con bastante facilidad y minimizar la cantidad de datos devueltos por SQL Server.

E.g. si la firma de su método es IQueryable <Cliente> GetCustomers() puede obtener un solo cliente llamando a GetCustomers(). Where (c => c.CustomerID == 101) .Single();

En este ejemplo, solo se devolverá un registro de la base de datos mientras que imagino que su código devolvería todos los clientes o se requerirá que escriba métodos separados (y por lo tanto un código muy repetitivo) para atender todos los diferentes cosas que tal vez quiera filtrar

+4

Recomiendo exactamente lo contrario. Nunca volvería un IQuerable sobre un IList fuera del DAL. Si lo hace, su capa de presentación probablemente terminará ejecutando inadvertidamente las consultas de la base de datos, o podría terminar mezclando llamadas de Linq a objetos y obtener un error de Linq a sql. La devolución de IQuerable de Linq a sql permite una arquitectura realmente pobre y con fugas, y debe evitarse para todas las aplicaciones de juguetes menos para las más pequeñas. – mattmc3

2

En mi opinión, en la mayoría de los casos, los objetos DTO no son necesarios cuando se trata de LINQ. Las clases LINQ generadas se pueden probar fácilmente. LINQ le da la capacidad de consultar sus datos desde diferentes fuentes utilizando consultas idénticas. Le da la capacidad de probar sus consultas contra listas de objetos en lugar de db real.

+0

Estoy de acuerdo. En esencia, sus objetos Linq-to-sql podrían tratarse como DTO, e incluso hay una plantilla T4 para generar sus objetos L2S como serializables. – mattmc3