.net - tutorial - ¿Pueden los objetos generados por LINQ to SQL estar desacoplados?
linq to sql vs entity framework (7)
Me gusta LINQ to SQL, pero parece que las clases que genera están estrechamente vinculadas a la base de datos en la que están almacenadas, lo que parece una cosa mala.
Por ejemplo, utilizando la base de datos de Older Northwind, si creo el dbml con la tabla Products, se genera una clase Product
. Puedo usar esta clase en cualquier otro nivel, lo que está muy bien, pero si decido que prefiero usar el viejo ADO.NET (o cambiar las bases de datos), tendré que recrear la clase de Product
, junto con cada otro "modelo".
¿Hay alguna forma de evitar esto? ¿O crear sus modelos de objetos por separado y luego asignarles las tablas? He jugado con las diversas clases de mapeo proporcionadas, pero aún no he encontrado una respuesta satisfactoria.
Oh hey, creo que encontré una solución a esto mientras veía las grabaciones de pantalla de Rob Conery en ASP.NET MVC . El truco es select
un objeto en tu consulta LINQ to SQL.
public IQueryable<LinqExample.Core.Person> GetAll() {
var people = from pe in this.db.Persons
select new Person {
Id = pe.id,
FirstName = pe.fname,
LastName = pe.lname,
Reports = this.GetReports(pe.id)
};
return people;
}
Esto te permite definir una clase Person
en otro lugar de tu código. Publiqué más sobre esto en profundidad.
Linq a SQL (o EF) no se trata de persistencia-ignorancia. Se trata de una vista de objetos de datos.
NHibernate es el ORM de persistencia e ignorancia que puede estar buscando.
Mi equipo luchó con este problema recientemente. Realmente quería mantener "la ignorancia de la persistencia", lo que significa que los objetos de dominio podrían crearse como simples objetos antiguos de C #, sin ser forzados a heredar de una cierta clase base o desordenar la clase con un conjunto de atributos. Como dijo, queríamos poder modificar la capa de persistencia independientemente del modelo de negocio.
Al final, decidimos que LINQ no es el camino a seguir si quieres ignorancia de persistencia. Terminamos escribiendo demasiado código de mapeo para convertir entre la capa LINQ y nuestra capa de negocios. Cuando comenzamos a escribir un montón de código basado en la reflexión para tratar de hacer estas asignaciones de forma automática, nos dimos cuenta de que nos estábamos deslizando por el agujero del conejo, con poco para demostrarlo.
Si la ignorancia de la persistencia es importante para usted, es posible que le sirva mejor un ORM completo como NHIbernate.
Scott Hanselman hizo una pantalla hablando sobre asp.net DynamicData donde utilizó las clases de Linq a Sql. Aunque él no estaba abordando el tema en particular, creo que el concepto general aún funcionaría. Su enfoque fue crear una clase parcial separada que tenía el mismo nombre que la clase, Product
en su caso, que fue generado por el dbml. Entonces siempre debe tener una clase de Product
que exista fuera de lo que LINQ genera y simplemente "amplíe" lo que hace.
Simplemente copie el código generado en sus propias clases y desactive la generación de código. La magia está en los atributos, no en otra cosa.
Alternativamente, puede escribir sus propios objetos CLR simples sin los atributos y usar un archivo de mapeo XML externo para describir la relación entre los objetos y la base de datos. Se puede encontrar más información en la documentación de LINQ to SQL en MSDN.
Todas estas respuestas y sin enlaces! Quizás puedo ayudar:
Los atributos que ese damieng menciona
La clase parcial que Marcus King mencionó
He languidecido a través de esta dificultad un par de veces, lo que terminé haciendo en mi último proyecto fue utilizar interfaces como el contrato que se comparte entre los diferentes proyectos en la solución, y hacer que las clases parciales lo implementen.
[Table(Name="Products")]
public partial class Product: IProduct { }
Y sí, desafortunadamente tomó algo de magia de reflexión para que funcione para la implementación de POCO.
Al final, si realmente te preocupa, iré con NHibernate (tampoco me gusta), que hace exactamente lo que Garry Shulter parece describir.
¡Espero que ayude!
Recientemente lo logré creando los POCO yo mismo y creando manualmente un archivo de mapeo XML para la base de datos. Requiere un poco de trabajo manual pero da el efecto deseado.
Aquí hay una publicación de blog que encontré útil para comenzar.