¿Entity Framework es adecuado para sitios web de alto tráfico?


176

¿Es Entity Framework 4 una buena solución para un sitio web público con potencialmente 1000 visitas / segundo?

Según tengo entendido, EF es una solución viable para sitios web más pequeños o de intranet, pero no se puede escalar fácilmente para algo como un sitio web popular de la comunidad (sé que SO está usando LINQ to SQL, pero ... Me gustaría obtener más ejemplos / pruebas. ..)

Ahora estoy en la encrucijada de elegir un enfoque ADO.NET puro o EF4. ¿Cree que la mejora de la productividad del desarrollador con EF vale la pena el rendimiento perdido y el acceso granular de ADO.NET (con procedimientos almacenados)? Cualquier problema serio que un sitio web de alto tráfico podría enfrentar, ¿estaba usando EF?

Gracias de antemano.


1
No entiendes la escala. Escalar significa obtener un rendimiento de 10x cuando agrega una capacidad de 10x. ¿Por qué EF evitaría que esto suceda? Agrega una sobrecarga de factor constante a cualquier carga de trabajo de la base de datos.
usr

Respuestas:


152

Depende un poco de la cantidad de abstracción que necesites . Todo es un compromiso; por ejemplo, EF y NHibernate introducen una gran flexibilidad para la representación de los datos en modelos interesantes y exóticos - pero como resultado que hacen agregar una sobrecarga. Sobrecarga notable.

Si no necesita poder cambiar entre proveedores de bases de datos y diferentes diseños de tabla por cliente, y si sus datos se leen principalmente , y si no necesita poder usar el mismo modelo en EF, SSRS , ADO.NET Data Services, etc., entonces si desea un rendimiento absoluto como su medida clave, podría hacer mucho peor que mirar a Dapper . En nuestras pruebas basadas en LINQ-to-SQL y EF, encontramos que EF es significativamente más lento en términos de rendimiento de lectura sin procesar, presumiblemente debido a las capas de abstracción (entre el modelo de almacenamiento, etc.) y la materialización.

Aquí en SO, somos obsesivos-compulsivos con respecto al rendimiento en bruto, y estamos contentos de recibir el golpe de desarrollo de perder algo de abstracción para ganar velocidad. Como tal, nuestra herramienta principal para consultar la base de datos es apta . Esto incluso nos permite usar nuestro modelo LINQ-to-SQL preexistente, pero simplemente: es mucho más rápido. En las pruebas de rendimiento, es esencialmente exactamente el mismo rendimiento que escribir todo el código ADO.NET (parámetros, lectores de datos, etc.) manualmente, pero sin el riesgo de que el nombre de una columna sea incorrecto. Sin embargo, está basado en SQL (aunque es feliz usar SPROC si ese es su veneno elegido). La ventaja de esto es que no hay un procesamiento adicional involucrado, pero es un sistema para personas a las que les gusta SQL. Lo que considero: ¡no es malo!

Una consulta típica, por ejemplo, podría ser:

int customerId = ...
var orders = connection.Query<Order>(
    "select * from Orders where CustomerId = @customerId ",
    new { customerId }).ToList();

lo cual es conveniente, seguro para inyección, etc., pero sin toneladas de pegajoso lector de datos. Tenga en cuenta que si bien puede manejar particiones horizontales y verticales para cargar estructuras complejas, no admitirá la carga diferida (pero: somos grandes admiradores de la carga muy explícita, menos sorpresas).

Tenga en cuenta en esta respuesta que no estoy diciendo que EF no es adecuado para trabajos de gran volumen; simplemente: que apuesto está a la altura.


25
+1 para apuesto. Usar un ORM complejo para leer modelos es simplemente innecesario. El enfoque que tomamos ahora es utilizar un ORM para nuestro modelo de dominio (donde el material ORM elegante es realmente útil) y apuesto para nuestro modelo de lectura. Esto lo convierte en aplicaciones súper rápidas.

2
@ Marc, gracias por la gran respuesta: ¡finalmente puedo tomar mi decisión con confianza! Definitivamente se verá en apuesto con más detalle más adelante. Realmente me gusta cómo es solo un archivo :)

3
Escribí mi propio ORM. Es lento. Miré apuesto y me gustó. Ahora uso dapper para todas mis lecturas y mi propio ORM para inserciones (que admite FK, transacciones y todo lo bueno). Es el código más fácil de leer que he escrito.

2
@ acidzombie24 dapper admite transacciones, y la parte contrib de dapper (no parte de la implementación de nuget) está ganando opciones de inserción, etc. Solo mencionando para completar. Me alegro de que Dapper fuera útil.
Marc Gravell

1
@anyname Nunca he hecho un video curso sobre ningún tema; Hay algunos videos por ahí, pero no por mí. Tiendo a ser una persona de palabra escrita
Marc Gravell

217

La pregunta "qué ORM debería usar" está realmente dirigida a la punta de un gran iceberg cuando se trata de la estrategia general de acceso a datos y la optimización del rendimiento en una aplicación a gran escala.

Todas las siguientes cosas ( aproximadamente en orden de importancia) afectarán el rendimiento, y todas ellas son manejadas (a veces de diferentes maneras) por la mayoría de los principales marcos de ORM:

  1. Diseño de bases de datos y mantenimiento

    Este es, por un amplio margen, el determinante más importante del rendimiento de una aplicación o sitio web basado en datos y, a menudo, totalmente ignorado por los programadores.

    Si no utiliza las técnicas de normalización adecuadas, su sitio está condenado. Si no tiene claves primarias, casi todas las consultas serán lentas. Si utiliza antipatrones bien conocidos, como el uso de tablas para pares de valores clave (AKA Entity-Attribute-Value) sin una buena razón, explotará la cantidad de lecturas y escrituras físicas.

    Si no aprovecha las características que le brinda la base de datos, como la compresión de páginas, el FILESTREAMalmacenamiento (para datos binarios), las SPARSEcolumnas, las hierarchyidjerarquías, etc. (todos los ejemplos de SQL Server), no verá nada cerca del rendimiento que podrías estar viendo.

    Debería comenzar a preocuparse por su estrategia de acceso a datos después de haber diseñado su base de datos y convencido de que es tan buena como sea posible, al menos por el momento.

  2. Carga ansiosa vs. perezosa

    La mayoría de los ORM usaban una técnica llamada carga diferida para las relaciones, lo que significa que, de manera predeterminada, cargará una entidad (fila de tabla) a la vez y realizará un viaje de ida y vuelta a la base de datos cada vez que necesite cargar uno o varios relacionados (externos clave) filas.

    Esto no es algo bueno o malo, sino que depende de lo que realmente se va a hacer con los datos y de cuánto sabes por adelantado. A veces, la carga diferida es absolutamente lo que hay que hacer. NHibernate, por ejemplo, puede decidir no consultar nada y simplemente generar un proxy para una ID en particular. Si todo lo que necesita es la identificación, ¿por qué debería pedir más? Por otro lado, si está intentando imprimir un árbol de cada elemento individual en una jerarquía de 3 niveles, la carga diferida se convierte en una operación O (N²), lo que es extremadamente malo para el rendimiento.

    Un beneficio interesante de usar "SQL puro" (es decir, consultas ADO.NET sin procesar / procedimientos almacenados) es que básicamente te obliga a pensar exactamente qué datos son necesarios para mostrar cualquier pantalla o página. ORM y características de carga perezosa no impiden que se haga esto, pero ellos no le dan la oportunidad de ser ... bueno, perezoso , y sin querer explotar el número de consultas que vaya haciendo. Por lo tanto, debe comprender las funciones de carga entusiasta de sus ORM y estar siempre atento a la cantidad de consultas que envía al servidor para cualquier solicitud de página determinada.

  3. Almacenamiento en caché

    Todos los ORM principales mantienen un caché de primer nivel, también conocido como "caché de identidad", lo que significa que si solicita la misma entidad dos veces por su ID, no requiere un segundo viaje de ida y vuelta (y si diseñó su base de datos correctamente) ) le ofrece la posibilidad de utilizar la simultaneidad optimista.

    El caché L1 es bastante opaco en L2S y EF, tienes que confiar en que está funcionando. NHibernate es más explícito al respecto ( Get/ Loadvs. Query/ QueryOver). Aún así, siempre que intente consultar por ID tanto como sea posible, debería estar bien aquí. Mucha gente se olvida del caché L1 y busca repetidamente la misma entidad una y otra vez por algo que no sea su ID (es decir, un campo de búsqueda). Si necesita hacer esto, debe guardar la ID o incluso la entidad completa para futuras búsquedas.

    También hay un caché de nivel 2 ("caché de consultas"). NHibernate tiene esto incorporado. Linq to SQL y Entity Framework han compilado consultas , lo que puede ayudar a reducir bastante las cargas del servidor de aplicaciones compilando la expresión de consulta en sí, pero no almacena en caché los datos. Microsoft parece considerar esto una preocupación de la aplicación en lugar de una preocupación de acceso a datos, y este es un punto débil importante tanto de L2S como de EF. No hace falta decir que también es un punto débil de SQL "en bruto". Para obtener un rendimiento realmente bueno con básicamente cualquier ORM que no sea NHibernate, debe implementar su propia fachada de almacenamiento en caché.

    También hay una "extensión" de caché L2 para EF4 que está bien , pero no es realmente un reemplazo total para un caché de nivel de aplicación.

  4. Numero de consultas

    Las bases de datos relacionales se basan en conjuntos de datos. Son muy buenos para producir grandes cantidades de datos en un corto período de tiempo, pero no son tan buenos en términos de latencia de consulta porque hay una cierta cantidad de sobrecarga involucrada en cada comando. Una aplicación bien diseñada debe aprovechar los puntos fuertes de este DBMS e intentar minimizar la cantidad de consultas y maximizar la cantidad de datos en cada una.

    Ahora no estoy diciendo que consulte toda la base de datos cuando solo necesita una fila. Lo que estoy diciendo es, si usted necesita las Customer, Address, Phone, CreditCard, y Orderfilas, todo al mismo tiempo con el fin de servir a una sola página, a continuación, usted debe preguntar por todos ellos al mismo tiempo, no ejecutar cada consulta por separado. A veces es peor que eso, verá un código que consulta el mismo Customerregistro 5 veces seguidas, primero para obtener el Id, luego el Name, luego el EmailAddress, luego ... es ridículamente ineficiente.

    Incluso si necesita ejecutar varias consultas que operan en conjuntos de datos completamente diferentes, generalmente es aún más eficiente enviarlo todo a la base de datos como un "script" único y hacer que devuelva múltiples conjuntos de resultados. Lo que le preocupa es la sobrecarga, no la cantidad total de datos.

    Esto puede sonar a sentido común, pero a menudo es muy fácil perder el rastro de todas las consultas que se ejecutan en varias partes de la aplicación; su proveedor de membresía consulta las tablas de usuario / rol, su acción de encabezado consulta el carrito de compras, su acción de menú consulta la tabla de mapa del sitio, su acción de barra lateral consulta la lista de productos destacados y luego su página se divide en algunas áreas autónomas separadas que consulta las tablas Historial de pedidos, Recientemente visto, Categoría e Inventario por separado, y antes de que te des cuenta, estás ejecutando 20 consultas antes de que puedas comenzar a servir la página. Simplemente destruye completamente el rendimiento.

    Algunos marcos, y estoy pensando principalmente en NHibernate aquí, son increíblemente inteligentes al respecto y le permiten usar algo llamado futuros que agrupa consultas completas e intenta ejecutarlas todas a la vez, en el último minuto posible. AFAIK, estás solo si quieres hacer esto con cualquiera de las tecnologías de Microsoft; tienes que construirlo en la lógica de tu aplicación.

  5. Indización, predicados y proyecciones

    Al menos el 50% de los desarrolladores con los que hablo e incluso algunos DBA parecen tener problemas con el concepto de índices de cobertura. Piensan: "bueno, la Customer.Namecolumna está indexada, por lo que cada búsqueda que haga del nombre debe ser rápida". Excepto que no funciona de esa manera a menos que el Nameíndice cubra la columna específica que está buscando. En SQL Server, eso se hace INCLUDEen la CREATE INDEXdeclaración.

    Si ingenuamente lo usa en SELECT *todas partes, y eso es más o menos lo que hará cada ORM a menos que especifique explícitamente lo contrario utilizando una proyección, entonces el DBMS puede elegir ignorar por completo sus índices porque contienen columnas no cubiertas. Una proyección significa que, por ejemplo, en lugar de hacer esto:

    from c in db.Customers where c.Name == "John Doe" select c
    

    Haces esto en su lugar:

    from c in db.Customers where c.Name == "John Doe"
    select new { c.Id, c.Name }
    

    Y esta voluntad, para la mayoría de ORM modernas, instruir sólo para ir y consultar las Idy Namecolumnas que son presumiblemente cubiertos por el índice (pero no el Email, LastActivityDateo cualquier otra columnas que le pasó a pegarse allí).

    También es muy fácil eliminar por completo cualquier beneficio de indexación mediante el uso de predicados inapropiados. Por ejemplo:

    from c in db.Customers where c.Name.Contains("Doe")
    

    ... parece casi idéntico a nuestra consulta anterior, pero de hecho dará como resultado una tabla completa o exploración de índice porque se traduce en LIKE '%Doe%'. Del mismo modo, otra consulta que parece sospechosamente simple es:

    from c in db.Customers where (maxDate == null) || (c.BirthDate >= maxDate)
    

    Suponiendo que tiene un índice BirthDate, este predicado tiene una buena oportunidad de volverlo completamente inútil. Nuestro programador hipotético aquí obviamente ha intentado crear una especie de consulta dinámica ("solo filtra la fecha de nacimiento si se especificó ese parámetro"), pero esta no es la forma correcta de hacerlo. Escrito así en su lugar:

    from c in db.Customers where c.BirthDate >= (maxDate ?? DateTime.MinValue)
    

    ... ahora el motor de base de datos sabe cómo parametrizar esto y hacer una búsqueda de índice. Un cambio menor, aparentemente insignificante, en la expresión de la consulta puede afectar drásticamente el rendimiento.

    Desafortunadamente, LINQ en general hace que sea demasiado fácil escribir consultas malas como esta porque a veces los proveedores pueden adivinar lo que estaba tratando de hacer y optimizar la consulta, y a veces no lo son. Por lo tanto, terminas con resultados frustrantemente inconsistentes que habrían sido cegadoramente obvios (para un DBA experimentado, de todos modos) si hubieras escrito un simple SQL antiguo.

    Básicamente, todo se reduce al hecho de que realmente tienes que vigilar de cerca tanto el SQL generado como los planes de ejecución a los que conducen, y si no estás obteniendo los resultados que esperas, no temas pasar por alto Capa ORM de vez en cuando y codifique manualmente el SQL. Esto se aplica a cualquier ORM, no solo a EF.

  6. Transacciones y Bloqueo

    ¿Necesita mostrar datos que estén actualizados hasta el milisegundo? Tal vez, depende, pero probablemente no. Lamentablemente, Entity Framework no te danolock , solo puedes usarlo READ UNCOMMITTEDa nivel de transacción (no a nivel de tabla). De hecho, ninguno de los ORM es particularmente confiable al respecto; si desea hacer lecturas sucias, debe desplegarse al nivel SQL y escribir consultas ad-hoc o procedimientos almacenados. Entonces, de nuevo, todo se reduce a lo fácil que es hacerlo dentro del marco.

    Entity Framework ha recorrido un largo camino en este sentido: la versión 1 de EF (en .NET 3.5) fue horrible, hizo increíblemente difícil romper la abstracción de "entidades", pero ahora tiene ExecuteStoreQuery y Translate , por lo que es realmente No está mal. Haz amigos con estos chicos porque los usarás mucho.

    También está el problema del bloqueo de escritura y los puntos muertos y la práctica general de mantener los bloqueos en la base de datos durante el menor tiempo posible. A este respecto, la mayoría de los ORM (incluido Entity Framework) en realidad tienden a ser mejores que SQL sin formato porque encapsulan la unidad del patrón de trabajo , que en EF es SaveChanges . En otras palabras, puede "insertar" o "actualizar" o "eliminar" entidades al contenido de su corazón, siempre que lo desee, con la certeza de que no se introducirán cambios en la base de datos hasta que confirme la unidad de trabajo.

    Tenga en cuenta que un UOW no es análogo a una transacción de larga duración. El UOW aún utiliza las características optimistas de concurrencia del ORM y rastrea todos los cambios en la memoria . No se emite una sola declaración DML hasta la confirmación final. Esto mantiene los tiempos de transacción lo más bajo posible. Si crea su aplicación utilizando SQL sin formato, es bastante difícil lograr este comportamiento diferido.

    Lo que esto significa específicamente para EF: haga que sus unidades de trabajo sean lo más gruesas posible y no las comprometa hasta que sea absolutamente necesario. Haga esto y terminará con una contención de bloqueo mucho menor que la que usaría los comandos individuales de ADO.NET en momentos aleatorios.

En conclusión:

EF está completamente bien para aplicaciones de alto tráfico / alto rendimiento, al igual que cualquier otro marco está bien para aplicaciones de alto tráfico / alto rendimiento. Lo que importa es cómo lo usas. Aquí hay una comparación rápida de los marcos más populares y las características que ofrecen en términos de rendimiento (leyenda: N = No compatible, P = Parcial, Y = sí / compatible):

                                | L2S | EF1 | EF4 | NH3 | ADO
                                +-----+-----+-----+-----+-----
Lazy Loading (entities)         |  N  |  N  |  N  |  Y  |  N
Lazy Loading (relationships)    |  Y  |  Y  |  Y  |  Y  |  N
Eager Loading (global)          |  N  |  N  |  N  |  Y  |  N
Eager Loading (per-session)     |  Y  |  N  |  N  |  Y  |  N
Eager Loading (per-query)       |  N  |  Y  |  Y  |  Y  |  Y
Level 1 (Identity) Cache        |  Y  |  Y  |  Y  |  Y  |  N
Level 2 (Query) Cache           |  N  |  N  |  P  |  Y  |  N
Compiled Queries                |  Y  |  P  |  Y  |  N  | N/A
Multi-Queries                   |  N  |  N  |  N  |  Y  |  Y
Multiple Result Sets            |  Y  |  N  |  P  |  Y  |  Y
Futures                         |  N  |  N  |  N  |  Y  |  N
Explicit Locking (per-table)    |  N  |  N  |  N  |  P  |  Y
Transaction Isolation Level     |  Y  |  Y  |  Y  |  Y  |  Y
Ad-Hoc Queries                  |  Y  |  P  |  Y  |  Y  |  Y
Stored Procedures               |  Y  |  P  |  Y  |  Y  |  Y
Unit of Work                    |  Y  |  Y  |  Y  |  Y  |  N

Como puede ver, a EF4 (la versión actual) no le va demasiado mal, pero probablemente no sea el mejor si el rendimiento es su principal preocupación. NHibernate es mucho más maduro en esta área e incluso Linq to SQL proporciona algunas características que mejoran el rendimiento que EF todavía no ofrece. Raw ADO.NET a menudo va a ser más rápido para escenarios de acceso a datos muy específicos , pero, cuando reúne todas las piezas, realmente no ofrece muchos beneficios importantes que obtiene de los diversos marcos.

Y, solo para asegurarme por completo de que sueno como un disco rayado , nada de esto importa en lo más mínimo si no diseñas tus bases de datos, aplicaciones y estrategias de acceso a datos correctamente. Todos los elementos en el cuadro anterior son para mejorar el rendimiento más allá de la línea de base; la mayoría de las veces, la línea de base en sí misma es lo que necesita más mejoras.


38
¡Qué respuesta tan asombrosa e integral!

2
+1 (más si pudiera) - una de las mejores respuestas que he visto en mucho tiempo aquí y aprendí una o dos cosas - ¡gracias por compartir esto!
BrokenGlass

1
Esta es una gran respuesta, incluso si no estoy de acuerdo con todo lo mencionado. La tabla que compara los ORM no siempre es correcta. ¿Qué es la carga diferida de entidades? ¿Te refieres a columnas cargadas perezosas? Eso es compatible con L2S. ¿Por qué crees que NH no admite consultas compiladas? Creo que las consultas HQL nombradas se pueden precompilar. EF4 no tiene soporte para múltiples conjuntos de resultados.
Ladislav Mrnka

11
Tengo que estar totalmente en desacuerdo con la declaración no calificada "EF está completamente bien para aplicaciones de alto tráfico / alto rendimiento", hemos visto repetidamente que este no es el caso. De acuerdo, tal vez no estemos de acuerdo con lo que significa "alto rendimiento", pero, por ejemplo, optimizar páginas web de hasta 500 ms y tener más de 400 ms de lo que se gasta inexplicablemente dentro del marco (y solo 10 ms realmente golpeando SQL) no está "bien" para algunas situaciones, Es totalmente inaceptable para nuestro equipo de desarrollo.
Nick Craver

1
Nota simple sobre futuros en EF. No son proporcionados oficialmente por el equipo de MS EF, pero pueden lograrse a través de proyectos de terceros que definen extensiones Future <> a IQueryable <>. Por ejemplo EntityFramework.Extended por LoreSoft, disponible en NuGet. Mis pruebas personales en aplicaciones de producción muestran una ganancia de rendimiento de hasta 10 veces cuando se empaquetan docenas de consultas no dependientes (todas las consultas se pueden ejecutar en paralelo, nadie requiere el resultado de una anterior) en un solo lote utilizando Future. También AsNoTracking () mejora mucho el rendimiento cuando solo lee muchos registros, sin actualizaciones posteriores.
David Oliván Ubieto

38

Editar: según la excelente respuesta de @Aaronaught, estoy agregando algunos puntos al rendimiento de orientación con EF. Esos nuevos puntos tienen el prefijo Edit.


La mayor mejora en el rendimiento en sitios web de alto tráfico se logra mediante el almacenamiento en caché (= en primer lugar, evitar el procesamiento del servidor web o las consultas de la base de datos) seguido del procesamiento asincrónico para evitar el bloqueo de subprocesos mientras se realizan las consultas de la base de datos.

No hay una respuesta a prueba de balas a su pregunta porque siempre depende de los requisitos de aplicación y de la complejidad de las consultas. La verdad es que la productividad del desarrollador con EF oculta la complejidad que, en muchos casos, conduce a un uso incorrecto de EF y un rendimiento terrible. La idea de que puede exponer una interfaz abstracta de alto nivel para el acceso a datos y que funcione sin problemas en todos los casos no funciona. Incluso con ORM debe saber qué está sucediendo detrás de la abstracción y cómo usarla correctamente.

Si no tiene experiencia previa con EF, enfrentará muchos desafíos al tratar con el rendimiento. Puede cometer muchos más errores al trabajar con EF en comparación con ADO.NET. También hay una gran cantidad de procesamiento adicional realizado en EF, por lo que EF siempre será significativamente más lento que ADO.NET nativo; eso es algo que puede medir con una simple aplicación de prueba de concepto.

Si desea obtener el mejor rendimiento de EF, lo más probable es que tenga que:

  • Revise cuidadosamente su acceso a datos con el generador de perfiles SQL y revise sus consultas LINQ si usan correctamente Linq-to-persons en lugar de Linq-to-objects
  • Utilice con mucho cuidado funciones avanzadas de optimización de EF como MergeOption.NoTracking
  • Use ESQL en algunos casos
  • Precompilar consultas que se ejecutan a menudo
  • Piense en aprovechar el contenedor EF Caching para obtener la función de "caché de segundo nivel" para algunas consultas
  • Use vistas SQL o consultas SQL mapeadas personalizadas (requiere el mantenimiento manual del archivo EDMX) en algunos escenarios para proyecciones o agregaciones de uso frecuente que necesitan mejoras de rendimiento
  • Utilice SQL nativo y procedimientos almacenados para algunas consultas que no proporcionan un rendimiento suficiente cuando se definen en Linq o ESQL
  • Editar: utilice cuidadosamente las consultas: cada consulta realiza un viaje de ida y vuelta por separado a la base de datos. EFv4 no tiene lotes de consultas porque no puede usar múltiples conjuntos de resultados por comando de base de datos ejecutado. EFv4.5 admitirá múltiples conjuntos de resultados para procedimientos almacenados mapeados.
  • Editar: trabaje cuidadosamente con modificaciones de datos. Una vez más, EF carece por completo de comandos por lotes . Por lo tanto, en ADO.NET puede usar un solo que SqlCommandcontiene múltiples inserciones, actualizaciones o eliminaciones, pero con EF cada comando se ejecutará en un viaje de ida y vuelta por separado a la base de datos.
  • Editar: trabaje con cuidado con el mapa de identidad / caché de identidad. EF tiene un método especial ( GetByKeyen ObjectContext API o Finden DbContext API) para consultar primero el caché. Si usa Linq-to-persons o ESQL, creará un viaje de ida y vuelta a la base de datos y luego devolverá la instancia existente del caché.
  • Editar: use con cuidado la carga ansiosa. No siempre es una solución beneficiosa para todos, ya que produce un gran conjunto de datos . Como puede ver, es una gran cantidad de complejidad adicional y ese es el punto. ORM simplifica el mapeo y la materialización, pero cuando se trata del rendimiento lo hará mucho más complejo y tendrá que hacer compensaciones.

No estoy seguro si SO todavía está usando L2S. Desarrollaron un nuevo ORM de código abierto llamado Dapper y creo que el punto principal detrás de este desarrollo fue aumentar el rendimiento.


Ladislav, esa es una respuesta realmente útil. Esta es la primera vez que escucho sobre Dapper (y, en consecuencia, descubrí PetaPoco, Massive), y parece una idea interesante.

1
SO parece utilizar una combinación de LINQ to SQL y Dapper ahora: samsaffron.com/archive/2011/03/30/… Cita: "Estamos utilizando nuestro nuevo ORM [Dapper] para un problema específico: mapear SQL parametrizado a objetos de negocios . No lo estamos usando como un ORM completo. No hace relaciones y otras campanas y silbatos. Esto nos permite continuar usando LINQ-2-SQL donde el rendimiento no importa y portar todo nuestro SQL en línea para usar nuestro mapeador, ya que es más rápido y más flexible ".

55
@Slauma bueno, esa es una declaración de hace meses, en general, todo el trabajo nuevo en SO se realiza en Dapper, por ejemplo, una nueva tabla que agregué hoy ni siquiera está en el archivo dbml.
Sam Saffron

1
@Sam: ¿Hay una nueva publicación de blog sobre la estrategia actual de acceso a datos en SO? ¡Sería muy interesante! ¿Se ha extendido Dapper mientras tanto? Comprendí que Dapper no es un ORM completo, no admite relaciones, y qué pasa con las actualizaciones, inserciones, eliminaciones, transacciones, seguimiento de cambios, etc.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.