2012-10-01 24 views
8

Estoy en las primeras etapas de la configuración de un nuevo proyecto de desarrollo y no estoy seguro de cómo configurar mi estrategia de acceso a la base de datos. Usaré Visual Studio 2012 y apuntaré a .NET 4.5 y SQL Server 2008 o 2012.Una combinación de Entity Framework, Dapper y SSDT?

Lo que no estoy seguro es si usar Entity Framework y, de ser así, en qué medida. Como leer datos de la base de datos y luego procesarlos será el trabajo principal para esta aplicación, el rendimiento de la consulta será importante. Sé que EF5 es mucho mejor que EF4.x en ese sentido, pero no es la sobrecarga de EF inherente lo que más me preocupa (aunque algo como Dapper todavía es al menos dos veces más rápido), sino más la pereza que te ofrece como desarrollador, porque consultar demasiado es tan fácil a través de LINQ. Por lo tanto, quiero que las consultas SQL puras sean la principal forma de obtener datos.

Sin embargo, lo que voy a extrañar de EF es:

  1. Compilar tiempo de verificación de la consulta.
  2. Seguimiento de cambios.
  3. primer desarrollo del código.
  4. Patrón de unidad de trabajo.

Puedo vivir sin el seguimiento de cambios, por lo general no es tan difícil determinar qué hay de nuevo o actualizado.

Lo que sí quiero es que los desarrolladores de este proyecto no tengan que perder el tiempo con los diseñadores de tablas, sino que simplemente puedan escribir POCO. Entonces, para eso, realmente aprecio el primer enfoque del código de EF. Con eso, un desarrollador puede clonar el código fuente, llamar al update-database y tener una base de datos local en funcionamiento. Es algo que funcionó bien para mí en el pasado.

Otra cosa que es muy importante para mí es un patrón de unidad de trabajo, o la atomicidad de las inserciones y actualizaciones. Quiero poner en cola todos los cambios y tener un solo punto donde llamo al SaveChanges. Con bibliotecas como DapperExtensions, obtienes un método Insert, pero inmediatamente hará la llamada a la base de datos. Puede convertirlo en atómico envolviendo una transacción, pero eso no es lo mismo que ponerlo en cola. Así que tendré que rodar algún tipo de mecanismo de cola yo mismo para esto.

Para la comprobación de consultas en tiempo de compilación, considero utilizar las herramientas de datos de SQL Server (SSDT). Las consultas serían procedimientos almacenados (para evitar grandes bloqueos de cadena de consulta en el código C#) y al usar SSDT, estos se pueden verificar en tiempo de compilación. Otra ventaja de SSDT es que puede implementar los procedimientos almacenados desde Visual Studio a una base de datos de destino. Y lo más importante, los scripts SQL para estos vivirían en control de fuente.

Así que con eso, mi solución sería básicamente consisten en tres tecnologías de acceso de datos:

Entity Framework

  • sería responsable de la creación de la base de datos de datamodels POCO.
  • Sería utilizado para insertar/actualizar datos a través de su patrón de unidad de trabajo. Una advertencia sería que primero tendría que Attach entidades que obtuvo a través de SQL para el contexto.

SSDT

  • se utilizaría para verificar scripts SQL en tiempo de compilación.
  • Permite que los guiones vivan en Git.
  • Despliega las cosas que EF no puede implementar en su base de datos.

Dapper/Micro otro ORM

  • sería utilizado para obtener los datos

no puedo evitar sentir que esto es un poco de una solución de Frankenstein donde utilizo varios partes y piezas de todo. Tampoco estoy seguro aún de que SSDT y EF trabajen juntos de una manera agradable. Este rápido ejemplo parece funcionar bien:

// Combo of Dapper, EF and a stored proc that was published through SSDT 
static void Main(string[] args) 
{ 
    var connectionString = ConfigurationManager 
    .ConnectionStrings["DbDataContext"].ConnectionString; 

    using (var conn = new SqlConnection(connectionString)) 
    using (var ctx = new DbDataContext()) 
    { 
    conn.Open(); 

    var product = conn.Query<Product>("GetProduct", 
     commandType: CommandType.StoredProcedure).First(); 

    ctx.Products.Attach(product); 

    var order = new Order 
    { 
     Product = product 
    }; 

    ctx.Orders.Add(order); 

    ctx.SaveChanges(); 

    } 
} 

Este enfoque parece que funcionaría, pero también es complicado. Pero si renuncio a SSDT, me perderé la comprobación de SQL en tiempo de compilación, si renuncio a Entity Framework, me perderé las inserciones de código primero y más fáciles y si renuncio al SQL directo, extrañaré en un gran pedazo de rendimiento.

¿Hay alguna alternativa que esté pasando por alto? Si no, ¿cuál es el mejor enfoque aquí?

+0

"la pereza que te ofrece como desarrollador": es tu trabajo no ser flojo; EF ofrece ingeniería para el rendimiento perfectamente. – millimoose

+1

Sí, pero no utiliza LINQ. Tendrá que ir a SQL en bruto y, a continuación, sigue siendo la mitad de la velocidad de ADO.NET/Dapper (http://goo.gl/ctD9f). También podría ir con Dapper para consultas. Sin embargo, quiero evitar grandes manchas anónimas de cadenas para consultas en código C#, por lo que miré a SSDT para moverlo fuera del código. – JulianR

+0

Está bien, pero esa es una cuestión de sobrecarga del framework que está fuera del control del desarrollador. Mi punto fue simplemente que "ofrece pereza" no es una buena razón para elegir o no elegir una tecnología. Si está dispuesto a canjear gastos generales por la "profundidad" de ORM, aún tiene la opción de evitar los problemas de rendimiento causados ​​por el problema de selección de N + 1. (Este problema también tiene un impacto significativo en el rendimiento, es tan fácil de encontrar en SQL sin procesar, y mucho más difícil de resolver porque escribir uberqueries masivos es más difícil en SQL que en LINQ.) – millimoose

Respuesta

3

Deberías echar un vistazo a ServiceStack.Orm.

https://github.com/ServiceStack/ServiceStack.OrmLite

Tiene un montón de características, incluyendo el modelo Gen usando archivos tt, y puede crear tablas db también.

Y es compatible con LINQ.

Y su loco rayo rápido.

+32

Genial, ahora tiene cuatro cosas para elegir. –

+0

Lo consideré, pero los "tipos complejos están bloqueados en un campo de texto" fue un poco desagradable, tengo que decir. Ni siquiera eso es relevante para mí, solo ... raro. Más algo que pertenece a un documento no estructurado NoSQL datastore. Que puede crear tablas desde POCO es bueno, pero no puede hacer migraciones.Está bien, porque SSDT puede, pero no veo su ventaja sobre Dapper o PetaPoco. – JulianR

+0

hmm Los tipos escalares/incorporados se conservan como se esperaba en OrmLite: solo las propiedades de tipo complejo se bloquean de forma transparente. Si otros Micro ORM no están haciendo esto, supongo que no son compatibles con las POCO con propiedades de tipo complejo (es mejor tener algo que funciona bien?). OrmLite también proporciona una API tipada que funciona en todos los RDBMS principales admitidos. – mythz