Entity Framework è adatto a siti Web ad alto traffico?


176

Entity Framework 4 è una buona soluzione per un sito Web pubblico con potenzialmente 1000 visite / secondo?

Nella mia comprensione, EF è una soluzione praticabile per siti Web per lo più piccoli o intranet, ma non si ridimensionerebbe facilmente per qualcosa di simile a un sito Web di comunità popolare (so che SO utilizza LINQ to SQL, ma ... Vorrei ulteriori esempi / prove. ..)

Ora mi trovo al crocevia di scegliere un approccio ADO.NET puro o EF4. Pensi che il miglioramento della produttività degli sviluppatori con EF valga la perdita di prestazioni e l'accesso granulare di ADO.NET (con stored procedure)? Qualche problema serio che potrebbe incontrare un sito Web ad alto traffico, utilizzava EF?

Grazie in anticipo.


1
Non capisci il ridimensionamento. Il ridimensionamento significa ottenere un throughput 10x quando si aggiunge una capacità 10x. Perché EF dovrebbe impedire che ciò accada? Aggiunge un sovraccarico di fattore costante a qualsiasi carico di lavoro del database.
usr

Risposte:


152

Dipende un po 'da quanta astrazione hai bisogno . Tutto è un compromesso; per esempio, EF e NHibernate introducono una grande flessibilità per la rappresentazione dei dati in modelli interessanti ed esotiche - ma, di conseguenza, fanno aggiungere in testa. Notevole sovraccarico.

Se non è necessario essere in grado di passare da provider di database a diversi layout di tabella per client e se i dati vengono letti principalmente e se non è necessario utilizzare lo stesso modello in EF, SSRS , ADO.NET Data Services, ecc. - Se vuoi prestazioni assolute come misura chiave potresti fare molto peggio che guardare dapper . Nei nostri test basati sia su LINQ-to-SQL che su EF, scopriamo che EF è significativamente più lento in termini di prestazioni di lettura non elaborate, presumibilmente a causa degli strati di astrazione (tra modello di archiviazione ecc.) E materializzazione.

Qui a SO, siamo ossessivi-compulsivi sulle prestazioni grezze e siamo felici di prendere il colpo di sviluppo di perdere qualche astrazione per guadagnare velocità. Di conseguenza, il nostro strumento principale per l'interrogazione del database è dapper . Questo ci consente persino di utilizzare il nostro modello LINQ-to-SQL preesistente, ma semplicemente: è molto più veloce. Nei test delle prestazioni, è essenzialmente esattamente la stessa prestazione della scrittura manuale di tutto il codice ADO.NET (parametri, lettori di dati, ecc.), Ma senza il rischio di sbagliare il nome di una colonna. Tuttavia, è basato su SQL (anche se è felice di usare SPROC se questo è il veleno scelto). Il vantaggio di questo è che non è necessaria alcuna elaborazione aggiuntiva, ma è un sistema per persone a cui piace SQL. Che considero: non è una brutta cosa!

Una query tipica, ad esempio, potrebbe essere:

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

che è conveniente, sicuro per l'iniezione, ecc., ma senza tonnellate di appannamento del lettore di dati. Si noti che sebbene sia in grado di gestire partizioni orizzontali e verticali per caricare strutture complesse, non supporterà il caricamento lento (ma: siamo grandi fan del caricamento molto esplicito - meno sorprese).

Nota in questa risposta non sto dicendo che EF non è adatto per lavori ad alto volume; semplicemente: so che dapper dipende da questo.


25
+1 per dapper. L'uso di un ORM complesso per i modelli letti è semplicemente superfluo. L'approccio che adottiamo ora è quello di utilizzare un ORM per il nostro modello di dominio (dove la roba ORM di fantasia è effettivamente utile) e dapper per il nostro modello di lettura. Questo rende le applicazioni super veloci.

2
@Marc, grazie per l'ottima risposta - Posso finalmente prendere la mia decisione con fiducia! Sicuramente esamineremo più dapper più in dettaglio in seguito. Mi piace molto come è solo un file :)

3
Ho scritto il mio ORM. È lento. Ho guardato dapper e mi è piaciuto. Ora uso dapper per tutte le mie letture e il mio ORM per inserti (che supporta FK, transazioni e tutte le cose buone). È il codice più facile da leggere che abbia mai scritto.

2
@ acidzombie24 dapper supporta le transazioni e la parte contrib di dapper (non parte della distribuzione nuget) sta guadagnando opzioni insert etc. Sto solo citando per completezza. Sono contento che dapper sia stato utile.
Marc Gravell

1
@nomeutente Non ho mai realizzato un corso video su nessun argomento; ci sono alcuni video là fuori, ma non da me. Tendo ad essere una persona con una parola scritta
Marc Gravell

217

La domanda "quale ORM dovrei usare" è davvero rivolta alla punta di un enorme iceberg quando si tratta della strategia generale di accesso ai dati e dell'ottimizzazione delle prestazioni in un'applicazione su larga scala.

Tutte le seguenti cose ( approssimativamente in ordine di importanza) influenzeranno la produttività, e tutte verranno gestite (a volte in modi diversi) dalla maggior parte dei principali framework ORM disponibili:

  1. Progettazione e manutenzione del database

    Questo è, in larga misura, il singolo determinante più importante del throughput di un'applicazione o di un sito Web basato sui dati, e spesso viene totalmente ignorato dai programmatori.

    Se non usi tecniche di normalizzazione adeguate, il tuo sito è condannato. Se non si dispone di chiavi primarie, quasi ogni query sarà lenta. Se utilizzi anti-pattern noti come l'utilizzo di tabelle per coppie chiave-valore (valore-attributo-entità AKA) senza una buona ragione, esploderai il numero di letture e scritture fisiche.

    Se non si sfruttano le funzionalità offerte dal database, come la compressione della pagina, l' FILESTREAMarchiviazione (per i dati binari), le SPARSEcolonne, le hierarchyidgerarchie e così via (tutti gli esempi di SQL Server), non si vedrà alcun punto vicino al le prestazioni che si potrebbe essere visto.

    Dovresti iniziare a preoccuparti della tua strategia di accesso ai dati dopo aver progettato il tuo database e esserti convinto che sia il migliore possibile, almeno per il momento.

  2. Desideroso vs. Caricamento pigro

    La maggior parte degli ORM utilizzava una tecnica chiamata caricamento lento per le relazioni, il che significa che per impostazione predefinita caricherà un'entità (riga della tabella) alla volta e farà un giro di andata e ritorno nel database ogni volta che deve caricare uno o più correlati (esterni chiave) righe.

    Questa non è una cosa buona o cattiva, piuttosto dipende da cosa verrà effettivamente fatto con i dati e da quanto sai in anticipo. A volte il caricamento lento è assolutamente la cosa giusta da fare. NHibernate, ad esempio, può decidere di non eseguire alcuna query e di generare semplicemente un proxy per un determinato ID. Se tutto ciò di cui hai bisogno è l'ID stesso, perché dovrebbe chiedere di più? D'altra parte, se si sta tentando di stampare un albero di ogni singolo elemento in una gerarchia a 3 livelli, il caricamento lento diventa un'operazione O (N²), che è estremamente dannosa per le prestazioni.

    Un vantaggio interessante dell'utilizzo di "SQL puro" (ovvero query ADO.NET non elaborate / stored procedure) è che in pratica ti costringe a pensare esattamente a quali dati sono necessari per visualizzare una determinata schermata o pagina. ORM e le caratteristiche pigro caricamento non impediscono dal fare questo, ma non ti danno la possibilità di essere ... beh, pigro , e accidentalmente esplodere il numero di query che si esegue. Quindi è necessario comprendere le funzionalità di caricamento entusiasta degli ORM ed essere sempre vigili sul numero di query che si inviano al server per una determinata richiesta di pagina.

  3. caching

    Tutti i principali ORM mantengono una cache di primo livello, la "cache delle identità" di AKA, il che significa che se si richiede la stessa entità due volte con il suo ID, non è necessario un secondo round-trip e anche (se il database è stato progettato correttamente ) ti dà la possibilità di utilizzare la concorrenza ottimistica.

    La cache L1 è piuttosto opaca in L2S ed EF, devi fidarti che funzioni. NHibernate è più esplicito al riguardo ( Get/ Loadvs. Query/ QueryOver). Tuttavia, finché cerchi di eseguire una query per ID il più possibile, dovresti andare bene qui. Molte persone dimenticano la cache L1 e cercano ripetutamente la stessa entità più e più volte da qualcosa di diverso dal suo ID (ad esempio un campo di ricerca). Se è necessario eseguire questa operazione, è necessario salvare l'ID o persino l'intera entità per ricerche future.

    C'è anche una cache di livello 2 ("query cache"). NHibernate ha questo built-in. Linq to SQL ed Entity Framework hanno compilato query , che possono aiutare a ridurre un po 'il carico del server delle app compilando l'espressione della query stessa, ma non memorizza nella cache i dati. Microsoft sembra considerarla una preoccupazione dell'applicazione piuttosto che una questione di accesso ai dati, e questo è un grave punto debole sia di L2S che di EF. Inutile dire che è anche un punto debole dell'SQL "grezzo". Per ottenere prestazioni davvero buone praticamente con qualsiasi ORM diverso da NHibernate, è necessario implementare la propria facciata cache.

    C'è anche una "estensione" cache L2 per EF4 che va bene , ma in realtà non è un sostituto all'ingrosso per una cache a livello di applicazione.

  4. Numero di query

    I database relazionali si basano su set di dati. Sono davvero bravi a produrre grandi quantità di dati in un breve lasso di tempo, ma non sono altrettanto buoni in termini di latenza delle query perché c'è un certo sovraccarico in ogni comando. Un'app ben progettata dovrebbe sfruttare i punti di forza di questo DBMS e cercare di ridurre al minimo il numero di query e massimizzare la quantità di dati in ciascuna.

    Ora non sto dicendo di interrogare l'intero database quando hai solo bisogno di una riga. Quello che sto dicendo è che, se avete bisogno di Customer, Address, Phone, CreditCard, e Orderle righe tutti allo stesso tempo, al fine di servire una singola pagina, allora si dovrebbe chiedere per tutti loro, allo stesso tempo, non si esegue ogni query separatamente. A volte è peggio di così, vedrai il codice che interroga lo stesso Customerrecord 5 volte di seguito, prima per ottenere il Id, poi il Name, poi il EmailAddress, quindi ... è ridicolmente inefficiente.

    Anche se è necessario eseguire diverse query che funzionano tutte su insiemi di dati completamente diversi, in genere è ancora più efficiente inviare tutto al database come un unico "script" e restituire più insiemi di risultati. È l'overhead che ti interessa, non la quantità totale di dati.

    Questo potrebbe sembrare un senso comune, ma spesso è davvero facile perdere traccia di tutte le query che vengono eseguite in varie parti dell'applicazione; il tuo provider di appartenenze interroga le tabelle utente / ruolo, l'azione dell'intestazione interroga il carrello, l'azione del menu interroga la tabella della mappa del sito, l'azione della barra laterale interroga l'elenco dei prodotti in primo piano e quindi forse la tua pagina è divisa in alcune aree autonome separate che interroga separatamente le tabelle Cronologia ordini, Visualizzati di recente, Categoria e Inventario e, prima di conoscerlo, stai eseguendo 20 query prima ancora di poter iniziare a pubblicare la pagina. Distrugge completamente le prestazioni.

    Alcuni framework - e sto pensando principalmente a NHibernate qui - sono incredibilmente intelligenti su questo e ti permettono di usare qualcosa chiamato futures che raggruppa intere query e cerca di eseguirle tutte in una volta, all'ultimo minuto possibile. AFAIK, sei da solo se vuoi farlo con una delle tecnologie Microsoft; devi inserirlo nella logica dell'applicazione.

  5. Indicizzazione, predicati e proiezioni

    Almeno il 50% degli sviluppatori con cui parlo e persino alcuni DBA sembrano avere problemi con il concetto di copertura degli indici. Pensano "bene, la Customer.Namecolonna è indicizzata, quindi ogni ricerca che faccio sul nome dovrebbe essere veloce". Solo che non funziona in questo modo a meno che l' Nameindice non copra la colonna specifica che stai cercando. In SQL Server, che è fatto con INCLUDEla CREATE INDEXdichiarazione.

    Se usi ingenuamente SELECT *ovunque - e questo è più o meno ciò che farà ogni ORM a meno che tu non specifichi esplicitamente diversamente usando una proiezione - allora il DBMS potrebbe benissimo scegliere di ignorare completamente i tuoi indici perché contengono colonne non coperte. Una proiezione significa che, ad esempio, invece di farlo:

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

    Fai invece questo:

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

    E questa volontà, per la maggior parte ORM moderni, istruzioni al fine di andare solo ed interrogare le Ide Namecolonne, che sono presumibilmente coperti dall'indice (ma non il Email, LastActivityDateo qualsiasi altro colonne ti è capitato di attaccare in là).

    È anche molto semplice eliminare completamente eventuali vantaggi dell'indicizzazione utilizzando predicati inappropriati. Per esempio:

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

    ... sembra quasi identico alla nostra query precedente ma in realtà si tradurrà in una scansione completa di tabella o indice perché si traduce in LIKE '%Doe%'. Allo stesso modo, un'altra query che sembra sospettosamente semplice è:

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

    Supponendo di avere un indice attivo BirthDate, questo predicato ha buone probabilità di renderlo completamente inutile. Il nostro ipotetico programmatore qui ha ovviamente tentato di creare una specie di query dinamica ("filtra la data di nascita solo se quel parametro è stato specificato"), ma questo non è il modo giusto per farlo. Scritto in questo modo invece:

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

    ... ora il motore DB sa come parametrizzare questo e fare una ricerca di indice. Una modifica minore, apparentemente insignificante, all'espressione della query può influire drasticamente sulle prestazioni.

    Sfortunatamente LINQ in generale rende fin troppo facile scrivere query cattive come questa perché a volte i provider sono in grado di indovinare cosa stavi cercando di fare e ottimizzare la query, a volte no. Quindi alla fine si ottengono risultati frustranti incoerenti che sarebbero stati palesemente ovvi (per un DBA esperto, comunque) se avessi appena scritto un semplice vecchio SQL.

    Fondamentalmente tutto si riduce al fatto che devi davvero tenere d'occhio sia l'SQL generato sia i piani di esecuzione che portano a, e se non stai ottenendo i risultati che ti aspetti, non aver paura di bypassare il Livello ORM di tanto in tanto e codice SQL manuale. Questo vale per qualsiasi ORM, non solo per EF.

  6. Transazioni e blocco

    Devi visualizzare i dati attuali fino al millisecondo? Forse - dipende - ma probabilmente no. Purtroppo, Entity Framework non ti dànolock , puoi usarlo solo READ UNCOMMITTEDa livello di transazione (non a livello di tabella). In effetti nessuno degli ORM è particolarmente affidabile al riguardo; se si desidera eseguire letture sporche, è necessario passare al livello SQL e scrivere query ad hoc o procedure memorizzate. Quindi ciò che si riduce a, ancora una volta, è quanto è facile per te farlo nel quadro.

    Entity Framework ha fatto molta strada in questo senso - la versione 1 di EF (in .NET 3.5) era terribile, ha reso incredibilmente difficile superare l'astrazione delle "entità", ma ora hai ExecuteStoreQuery e Translate , quindi è davvero non male. Fai amicizia con questi ragazzi perché li userai molto.

    C'è anche il problema del blocco della scrittura e dei deadlock e la pratica generale di tenere i blocchi nel database il meno tempo possibile. A questo proposito, la maggior parte degli ORM (incluso Entity Framework) tende ad essere migliore dell'SQL grezzo perché incapsulano l' unità del modello di lavoro , che in EF è SaveChanges . In altre parole, puoi "inserire" o "aggiornare" o "eliminare" entità nel contenuto del tuo cuore, quando vuoi, assicurandoti che nessuna modifica verrà effettivamente trasferita al database fino a quando non commetti l'unità di lavoro.

    Si noti che un UOW non è analogo a una transazione di lunga durata. UOW utilizza ancora le funzionalità di concorrenza ottimistica dell'ORM e tiene traccia di tutte le modifiche in memoria . Non viene emessa una singola istruzione DML fino al commit finale. Ciò consente di ridurre al minimo i tempi di transazione. Se si sviluppa l'applicazione utilizzando SQL non elaborato, è abbastanza difficile ottenere questo comportamento differito.

    Cosa significa questo per EF: Rendi le tue unità di lavoro il più grossolane possibile e non impegnarle fino a quando non ne avrai assolutamente bisogno. Fai questo e finirai con una contesa di blocco molto più bassa di quella che utilizzeresti i singoli comandi ADO.NET in momenti casuali.

In conclusione:

EF va benissimo per le applicazioni ad alto traffico / alte prestazioni, proprio come ogni altro framework va bene per le applicazioni ad alto traffico / alte prestazioni. Ciò che conta è come lo usi. Ecco un rapido confronto tra i framework più popolari e le funzionalità che offrono in termini di prestazioni (legenda: N = non supportato, P = parziale, Y = sì / supportato):

                                | 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

Come puoi vedere, EF4 (la versione attuale) non va troppo male, ma probabilmente non è il massimo se le prestazioni sono la tua preoccupazione principale. NHibernate è molto più maturo in quest'area e anche Linq to SQL offre alcune funzionalità che migliorano le prestazioni che EF non ha ancora. ADO.NET non elaborato sarà spesso più veloce per scenari di accesso ai dati molto specifici , ma, quando si mettono insieme tutti i pezzi, in realtà non offre molti vantaggi importanti che si ottengono dai vari framework.

E, solo per essere completamente sicuro che sembro un record rotto, nulla di tutto questo è minimamente se non si progettano correttamente il database, l'applicazione e le strategie di accesso ai dati. Tutti gli elementi nella tabella sopra sono per migliorare le prestazioni oltre la linea di base; la maggior parte delle volte, la base stessa è ciò che richiede il massimo miglioramento.


38
Che risposta fantastica e completa!

2
+1 (più se potessi) - una delle migliori risposte che ho visto da un po 'qui e ho imparato una cosa o due - grazie per averlo condiviso!
BrokenGlass

1
Questa è un'ottima risposta, anche se non sono d'accordo con tutto quanto menzionato. La tabella che confronta gli ORM non è sempre corretta. Che cos'è il caricamento lento delle entità? Intendi colonne caricate in modo pigro? Questo è supportato in L2S. Perché pensi che NH non supporti le query compilate? Penso che le query denominate HQL possano essere precompilate. EF4 non ha supporto per più set di risultati.
Ladislav Mrnka,

11
Devo fortemente in disaccordo con il qualificato "EF è completamente bene per le applicazioni ad alto traffico / ad alto rendimento" dichiarazione, abbiamo visto più volte che questo non è il caso. Certo, forse non siamo d'accordo su cosa significhi "alte prestazioni", ma ad esempio l'ottimizzazione di pagine Web fino a 500 ms e la presenza di oltre 400 ms di quella spesa inspiegabilmente all'interno del framework (e solo 10 ms in realtà colpendo SQL) non è "buona" per alcune situazioni, è assolutamente inaccettabile per il nostro team di sviluppo.
Nick Craver

1
Semplice nota sui futuri in EF. Non sono forniti ufficialmente dal team di MS EF ma possono essere realizzati attraverso progetti di terze parti che definiscono le future estensioni di IQueryable <>. Ad esempio EntityFramework.Extended by LoreSoft, disponibile in NuGet. I miei test personali nelle applicazioni di produzione mostrano un aumento delle prestazioni fino a 10 volte quando si confezionano dozzine di query non dipendenti (tutte le query possono essere eseguite in parallelo, nessuno richiede il risultato di una precedente) in un singolo batch utilizzando Future. Anche AsNoTracking () migliora molto le prestazioni quando si leggono molti record, senza aggiornamenti successivi.
David Oliván Ubieto,

38

Modifica: in base alla grande risposta di @Aaronaught, sto aggiungendo alcuni punti relativi alle prestazioni con EF. Questi nuovi punti sono preceduti da Modifica.


Il più grande miglioramento delle prestazioni nei siti Web ad alto traffico è ottenuto dalla memorizzazione nella cache (= innanzitutto evitando qualsiasi elaborazione del server Web o query del database) seguita dall'elaborazione asincrona per evitare il blocco dei thread durante l'esecuzione delle query del database.

Non esiste una risposta a prova di proiettile alla tua domanda perché dipende sempre dai requisiti per l'applicazione e dalla complessità delle query. La verità è che la produttività degli sviluppatori con EF nasconde la complessità dietro la quale in molti casi porta a un uso errato di EF e prestazioni terribili. L'idea che è possibile esporre l'interfaccia astratta di alto livello per l'accesso ai dati e funzionerà senza problemi in tutti i casi non funziona. Anche con ORM devi sapere cosa sta succedendo dietro l'astrazione e come usarlo correttamente.

Se non hai precedenti esperienze con EF, dovrai affrontare molte sfide quando ti occupi delle prestazioni. Puoi fare molti più errori quando lavori con EF rispetto ad ADO.NET. Inoltre, ci sono molte altre elaborazioni eseguite in EF, quindi EF sarà sempre significativamente più lenta di ADO.NET nativo - questo è qualcosa che puoi misurare con una semplice applicazione di prova del concetto.

Se desideri ottenere le migliori prestazioni da EF, molto probabilmente dovrai:

  • Revisiona attentamente l'accesso ai dati con il profiler SQL e rivedi le tue query LINQ se utilizzano correttamente Linq-to-entity anziché Linq-to-object
  • Usa con molta attenzione funzionalità avanzate di ottimizzazione EF come MergeOption.NoTracking
  • Utilizzare ESQL in alcuni casi
  • Query di pre-compilazione che vengono eseguite spesso
  • Pensa a sfruttare il wrapper EF Caching per ottenere funzionalità di "cache di secondo livello" come per alcune query
  • Utilizzare viste SQL o query SQL mappate personalizzate (richiede il mantenimento manuale del file EDMX) in alcuni scenari per proiezioni o aggregazioni spesso utilizzate che richiedono miglioramenti delle prestazioni
  • Utilizzare SQL nativo e stored procedure per alcune query che non forniscono prestazioni sufficienti se definite in Linq o ESQL
  • Modifica: usa con attenzione le query: ogni query effettua un round trip separato nel database. EFv4 non ha un batch di query perché non è in grado di utilizzare più set di risultati per comando di database eseguito. EFv4.5 supporterà più set di risultati per le procedure memorizzate mappate.
  • Modifica: lavora con attenzione con le modifiche ai dati. Ancora una volta EF manca completamente il comando batch . Quindi in ADO.NET è possibile utilizzare singoli SqlCommandcontenenti più inserimenti, aggiornamenti o eliminazioni, ma con EF ogni comando di questo tipo verrà eseguito in round trip separato per il database.
  • Modifica: lavora con attenzione con la mappa delle identità / cache delle identità. EF ha un metodo speciale ( GetByKeynell'API ObjectContext o Findnell'API DbContext) per interrogare prima la cache. Se si utilizza Linq-to-entity o ESQL, verrà creato roundtrip nel database e successivamente verrà restituita l'istanza esistente dalla cache.
  • Modifica: utilizzare con attenzione il caricamento desideroso. Non è sempre una soluzione vantaggiosa per tutti perché produce un enorme set di dati . Come puoi vedere è molta ulteriore complessità e questo è il punto. ORM semplifica la mappatura e la materializzazione ma, quando si tratta di prestazioni, la renderà molto più complessa e sarà necessario effettuare dei compromessi.

Non sono sicuro che SO stia ancora usando L2S. Hanno sviluppato un nuovo ORM open source chiamato Dapper e penso che il punto principale dietro questo sviluppo sia stato l'aumento delle prestazioni.


Ladislav, questa è una risposta davvero utile. Questa è la prima volta che sento parlare di Dapper (e di conseguenza ho scoperto PetaPoco, Massive) - e sembra un'idea interessante.

1
SO sembra usare un mix di LINQ to SQL e Dapper ora: samsaffron.com/archive/2011/03/30/… Citazione: "Stiamo usando il nostro nuovo ORM [Dapper] per un problema specifico: mappare SQL parametrizzato su oggetti business Non lo stiamo usando come un ORM completo. Non fa relazioni e altri campanelli e fischietti. Questo ci consente di continuare a utilizzare LINQ-2-SQL dove le prestazioni non contano e portiamo tutto il nostro SQL inline per usare il nostro mappatore, poiché è più veloce e più flessibile ".

5
@Slauma bene, questa è una dichiarazione di mesi fa, in generale tutto il nuovo lavoro su SO è fatto in Dapper, ad esempio una nuova tabella che ho aggiunto oggi non è nemmeno nel file dbml.
Sam Saffron,

1
@Sam: esiste un nuovo post sul blog sull'attuale strategia di accesso ai dati su SO? Sarebbe molto interessante! Nel frattempo Dapper è stato esteso? La mia comprensione era che Dapper non è un ORM completo, nessun supporto alle relazioni - e che dire di aggiornamenti, inserimenti, eliminazioni, transazioni, rilevamento delle modifiche, ecc.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.