c# - stored - Por qué Entity Framework se desempeña más rápido que Dapper en la declaración de selección directa
diferencias entre ado.net y entity framework (4)
El artículo Entity Framework Core 2.0 vs. Dapper rendimiento de referencia, al consultar las tablas de SQL Azure confirma que Dapper es un poco más rápido, pero no lo suficiente como para ignorar los beneficios de "ORM completo".
Soy nuevo en el uso de ORM para tratar con la base de datos, actualmente estoy haciendo un nuevo proyecto y tengo que decidir si usaré Entity Framework o Dapper. Leí muchos artículos que dicen que Dapper es más rápido que Entity Framework.
Así que hice 2 proyectos prototipos simples, uno usando Dapper y el otro Entity Framework con una función para obtener todas las filas de una tabla. El esquema de la tabla como la siguiente imagen.
y el código para ambos proyectos como el siguiente
para el proyecto Dapper
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
IEnumerable<Emp> emplist = cn.Query<Emp>(@"Select * From Employees");
sw.Stop();
MessageBox.Show(sw.ElapsedMilliseconds.ToString());
para Entity Framework Project
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
IEnumerable<Employee> emplist = hrctx.Employees.ToList();
sw.Stop();
MessageBox.Show(sw.ElapsedMilliseconds.ToString());
después de probar el código anterior muchas veces, solo la primera vez que ejecuto el proyecto, el código dapper será más rápido y, después de esta primera vez, siempre obtengo mejores resultados del proyecto del marco de la entidad. También intenté la siguiente declaración sobre el proyecto del marco de la entidad para detener a los perezosos. cargando
hrctx.Configuration.LazyLoadingEnabled = false;
pero sigue siendo el mismo EF realiza más rápido, excepto por primera vez.
¿Puede alguien darme una explicación u orientación sobre qué hace que EF sea más rápido en esta muestra, aunque todos los artículos en la web dicen lo contrario?
Actualizar
He cambiado la línea de código en el ejemplo de entidad para ser
IEnumerable<Employee> emplist = hrctx.Employees.AsNoTracking().ToList();
El uso de AsNoTracking como se menciona en algunos artículos detiene el almacenamiento en caché del marco de la entidad y, después de detener el almacenamiento en caché, el ejemplo de dapper se está desempeñando mejor (pero no es una gran diferencia)
No hay problema para mezclarlos juntos. En mi proyecto actual, estoy usando Dapper para seleccionar datos y EF para crear y actualizar y migraciones de bases de datos.
Dapper se vuelve extremadamente útil cuando se trata de consultas complejas donde hay más de dos tablas involucradas o donde hay algunas operaciones complejas (se unen más de una columna, se unen con> = y <= cláusulas, selecciones recursivas, cte, etc.) donde usar SQL puro es mucho más fácil que LINQ. Como sé, Entity Framework (a diferencia de Dapper) no puede usar el método .FromSql () en DTO personalizados. Puede asignar solo una tabla que debería estar en el contexto de su base de datos.
ORM (Object Relational Mapper) es una herramienta que crea una capa entre su aplicación y la fuente de datos y le devuelve los objetos relacionales en lugar de (en términos de c # que está usando) objetos ADO.NET. Esto es lo básico que hace cada ORM.
Para hacer esto, los ORM generalmente ejecutan la consulta y asignan el DataReader
devuelto a la clase POCO. Dapper se limita hasta aquí.
Para ampliar esto aún más, algunos ORM (también llamados "ORM completo") hacen muchas más cosas como generar consultas para que su base de datos de aplicaciones sea independiente, almacenar en caché sus datos para futuras llamadas, administrar la unidad de trabajo para usted y mucho más. Todas estas son buenas herramientas y agregan valor a ORM; Pero viene con costo. Entity Framework cae en esta clase.
Para generar la consulta, EF tiene que ejecutar código adicional. La memoria caché mejora el rendimiento, pero la administración de la memoria caché necesita ejecutar código adicional. Lo mismo es cierto para la unidad de trabajo y cualquier otra característica adicional proporcionada por EF. Todo esto le ahorra escribir código adicional y EF paga el costo.
Y el costo es el rendimiento. Como Dapper hace un trabajo muy básico, es más rápido; Pero tienes que escribir más código. Como EF hace mucho más que eso, es (un poco) más lento; Pero tienes que escribir menos código.
Entonces, ¿por qué sus pruebas muestran resultados opuestos?
Porque las pruebas que estás ejecutando son muy básicas. No está utilizando otras funciones proporcionadas por EF. Si no desea usar esas funciones, ¿por qué no usar Dapper? Si desea utilizar esas funciones, afectará ligeramente el rendimiento según la teoría anterior.
No es parte de su pregunta, pero la curva de aprendizaje diferente para esos dos también se debe a los mismos puntos mencionados anteriormente.
I read many articles which says that Dapper is faster than Entity Framework
El problema con la mayoría de los puntos de referencia en Internet es que comparan EF Linq con Dapper. Y eso es lo que hiciste también. Lo cual es injusto. Una consulta generada automáticamente (EF) a menudo no es igual a la escrita por un buen desarrollador.
Esta,
IEnumerable<Employee> emplist = hrctx.Employees.ToList();
debe ser reemplazado por este
IEnumerable<Employee> emplist = hrctx.Employees.FromSql(@"Select * From Employees").AsNoTracking();
Editar:
Como lo señaló @mjwills, a continuación se muestra la tabla de resultados para insert
, update
y select
declaraciones.
Dapper está superando a EF Core 2. Sin embargo, se puede ver que para las consultas sencillas de EF, la diferencia es mínima. He publicado los detalles completos aquí .