2009-05-17 2 views
6

Me encanta LINQ to SQL pero me ha estado molestando que al usarlo, mi código de repositorio sea generado por el marco LINQ to SQL y por lo tanto esté estrechamente acoplado a una base de datos SQL Server.¿Cómo resuelves tu código de persistencia cuando utilizas LINQ to SQL?

¿Alguno de ustedes está utilizando LINQ to SQL de una manera resumida y poco compacta y, de ser así, cómo se planteó el problema de mantener el código independiente de la base de datos?

Respuesta

3

Para mí; Estoy contento de volver a utilizar el modelo de objetos que LINQ/dbml genera, ya que en realidad los atributos no me duelen, y cualquier otra implementación podría proporcionar un modelo similar, pero no uso mi contexto de datos fuera del DAL. Así que tengo algo así como:

  • IFooRepository - define los métodos disponibles usando tanto los objetos DBML generados y algunas clases del modelo POCO
  • FooRepository - la implementación que sabe acerca de los datos del contexto

Mi los métodos de repositorio no exponen los conceptos LINQ como IQueryable<T> y Expression<...>, ya que son leaky abstractions; otras implementaciones funcionarán de manera diferente (EF soporta diferentes aspectos de ambas, por ejemplo).

Además - He comenzado a marcar la mayoría de las propiedades de asociación como internas, y solo las uso durante las consultas DAL (no tanto durante el trabajo OO).

Podría mapear a POCO puro, pero no veo el beneficio. Tengo más pensamientos sobre esto aquí: Pragmatic LINQ.

+0

Marc, buena publicación en el blog. +1 –

1

Puede utilizar un enfoque similar al utilizado en NerdsDinner. Este proyecto usa el contexto dat a como una puerta de entrada a la base de datos y construye un repositorio a su alrededor.

Este tipo de patrón de depósito agrega algunas condiciones, filtros, comando de ordenación ... etc. de acuerdo con el método llamado y luego devuelve un IQuerable a la persona que llama dejando la puerta abierta para modificaciones adicionales.

En realidad, usted hace casi lo mismo al construir un repositorio alrededor de una ISession NHibernate.

Si decidió reemplazar LinqtoSql con NHibernate, por ejemplo, solo tiene que consultar una sesión Linq dentro de su repositorio en lugar del contexto de datos. Por supuesto que necesitará, aunque para completar sus clases parciales con las propiedades, que LinqtoSql agrega automáticamente.

-1

Mouk anterior menciona el patrón de repositorio en el NerdsDinner, también hay un tutorial de cómo configurar rápidamente hasta aquí:

http://www.asp.net/learn/mvc/tutorial-10-cs.aspx

Esto una buena pequeña serie de tutoriales que se publicaron antes de la NerdsDinner. El concepto aquí también se puede configurar en una aplicación de formularios web asp.net tradicional.

Además, se recomienda usar LINQ a las entidades (más reciente, y más apoyo a otro DB) en su lugar, algunos conceptos básicos sobre el que están aquí: http://www.asp.net/learn/mvc/tutorial-16-cs.aspx

0

Hey Nathan, buena pregunta.

Como han dicho otros, lo mejor que puede hacer es abstraer todos sus métodos GET/WRITE, y esconder completamente el DataContext de su lógica de negocios.

Mi enfoque para esto ha sido escribir un DAL con un montón de métodos genéricos que usan la reflexión para hacer lo que sea necesario.

En estos casos, una vez que el método recibe un objeto, digamos "Producto", puede hacer lo que quiera internamente, independientemente de su tecnología ORM/Acceso a datos. Si lo desea, podría literalmente simplemente escribir una cadena de SQL en función de unos pocos parámetros y la reflexión del objeto.

SIN EMBARGO, hacer esto solo no lo desvinculará completamente de LINQ a SQL.

El problema en realidad son las entidades mismas. Incluso si abstrae el método para recuperar datos, aún estará usando esas Entidades en su lógica empresarial.

Siento que, de momento, es algo con lo que estoy dispuesto a vivir, porque volver a escribir mis propias Entidades desconectadas parece un puente que todavía no estoy dispuesto a cruzar, solo porque parece una gran cantidad de trabajo innecesario ...

Estaría muy interesado en ver cómo otros abordan esto sin embargo.

¡salud!

+0

Sí, ese es mi problema principal también. Tal vez las entidades podrían extraerse como interfaces? De esta forma, puede controlar su diseño con LINQ to SQL como de costumbre, obteniendo la ventaja de generación de código, incluso con la extracción de la interfaz, pero luego tiene un conjunto adecuado de interfaces para mantener las cosas abstractas. –

+0

hmm ... espera, por lo que dices, genera las clases a través de LINQ to SQL. Y luego, en su código, use sus propias clases que están desactualizadas para LINQ to SQL, pero pídales que implementen interfaces que coincidan con sus respectivas clases LINQ to SQL. ¿está bien? Puedo ver a dónde vas con esto, es una idea genial. Aunque no estoy seguro de los detalles, ¿tal vez podrías aclarar? Mi única preocupación es que todavía tienes que escribir un código extra repetitivo (?). Además, ahora que lo pienso, perderíamos las vinculaciones finales y las relaciones con la Entidad ... ¿qué piensas? – andy

+0

Estaba sugiriendo que si toda la lógica de negocios y el código de presentación hacía referencia a las entidades a través de sus interfaces, teóricamente podría descartar las entidades generadas por completo si fuera necesario, manteniendo todo el código linq dentro del repositorio y usar las clases parciales para asegurar que las entidades generadas "implementan" las interfaces. Entonces, todo lo que tenemos que hacer es usar Resharper u otra cosa para empujar a todos los miembros expuestos públicamente de las entidades a la interfaz. Entonces habría muy poco código adicional para escribir, aparte de mantener las interfaces actualizadas. –