Domanda

Sto decidendo un ORM per un grande progetto ed ero determinato a scegliere ADO.NET Entity Framework, in particolare la sua nuova versione fornita con .NET 4.Durante la mia ricerca di informazioni su EF mi sono imbattuto in Voto di sfiducia in ADO .NET Entity Framework che non sono sicuro di come prendere.

Il voto di sfiducia è stato scritto nel 2008 per convincere Microsoft ad ascoltare critiche specifiche per EF v1.

Non è chiaro se le affermazioni fatte nel voto di sfiducia siano ancora valide (in .NET 4) e se siano abbastanza serie da utilizzare altre soluzioni.NHibernate è un'alternativa matura, ma non so quali problemi comporti.In genere sono più propenso verso una soluzione Ms, soprattutto perché posso contare sull'integrazione con VS e sul loro supporto da parte degli sviluppatori.

Gradirei esempi di come i problemi menzionati nel voto di sfiducia incidono sui progetti del mondo reale. Ancora più importante, le affermazioni fatte sono ancora rilevanti in EF per .NET 4?

È stato utile?

Soluzione

Ho sempre pensato che gran parte di ciò che stava alla base del "voto di sfiducia" fosse un tentativo di utilizzare EF come se fosse un clone di NHibernate.Non lo è, e anche in EF 4 il tentativo di utilizzare EF come se fosse un knockoff di NHibernate probabilmente finirà con un fallimento, anche se potresti andare un po' oltre prima di fallire.Come esempio banale, la maggior parte delle persone utilizza LINQ in NHibernate in modo minimo, se non del tutto, mentre non penso che tu possa essere produttivo in EF affatto a meno che tu non usi LINQ abbastanza pesantemente.

D'altra parte, ho avuto abbastanza successo nell'utilizzare l'EF 1 alle sue condizioni e sono riuscito a non consentire che le affermazioni che le persone fanno nei post del blog ostacolino il suo funzionamento per me.Non vedo l'ora di utilizzare molte delle nuove funzionalità di EF 4, ma sarei felice di lavorare su un progetto EF 1 ben strutturato in qualsiasi momento.(Del resto, sono felice di lavorare anche con NHibernate e non lo criticherei per non comportarsi come EF.)

Quindi sto cercando di suggerire, in modo piuttosto delicato, che prima di poter decidere se "le affermazioni fatte nel voto di sfiducia sono ancora valide (in .NET 4)..." devi prima decidere se tali affermazioni erano sempre valido per te e per il modo in cui Voi lavoro. Se la tua comprensione personale di O/R è collegata a NHibernate, allora EF 4 probabilmente ti sembrerà ancora di second'ordine.Se, d'altra parte, sei disposto a imparare il modo di lavorare di EF, probabilmente anche EF 1 ti sembrerà migliore di quanto hai sentito.

Per affrontare direttamente le affermazioni di "sfida" ed esaminare sia la loro sostanza sia le modifiche apportate in EF 4:

UNA FOCUS INORDINATA L'ASPETTO DEI DATI DELLE ENTITÀ PORTA AD ARCHITETTURE DI ENTITÀ DEGRADATE:

Si tratta di un malinteso del modello di dati dell'entità di Entity Framework.(O, una differenza di opinione, se preferisci.) Ma in ogni caso, è una funzionalità, non un bug.L'Entity Framework è progettato attorno al caso più generale dei servizi dati, non solo alla modellazione O/R in particolare.L'implementazione di comportamenti sulle entità restituite da un servizio dati porta a un disastro in stile CORBA.A differenza degli ORM in cui sei, in una certa misura, bloccato con qualunque tipo esca dalla scatola nera ORM, con il modello Entity Framework dovresti proiettare sui tipi di business.In questo caso, i tipi di entità mappati non verranno mai nemmeno materializzati.

Questa è una differenza sostanziale tra il modello Entity Framework e molti altri ORM.Personalmente, trovo che separare i comportamenti aziendali dalla mappatura O/R sia un po' più pulito che metterli insieme.Non è necessario essere d'accordo con questa idea, ma è chiaramente una decisione progettuale, non una svista.

CODICE IN ECCESSO NECESSARIO PER GESTIRE LA MANCANZA DI LAZY LOADING:

L'EF 4, nel bene e nel male, ha un caricamento lento.

Dico "nel bene e nel male" perché il caricamento lento rende molto facile generare query di database in eccesso.Funziona bene fintanto che tieni d'occhio cosa succede sotto il cofano, ma la maggior parte delle persone non lo fa.io trovo proiezione per essere un'alternativa migliore al caricamento lento, al caricamento entusiasta o al caricamento esplicito per la maggior parte del tempo.

Tuttavia, ci sono momenti in cui il caricamento lento è conveniente.Quindi sono felice di vederlo aggiunto in EF 4.

IL MODELLO CANONICO CONDIVISO CONTRADDA LE MIGLIORI PRATICHE DEL SOFTWARE:

È difficile sapere cosa pensare, poiché parte del testo di supporto non è nemmeno un inglese coerente, ad esempio:

L’approccio del modello canonico incline al fallimento non è stato difficile per la mancanza di strumenti elaborati sulla falsariga dell’Entity Framework.

Questa sezione sembra per suggerire che l'Entity Framework impone una sorta di requisito, o almeno un forte pregiudizio, verso l'utilizzo di un unico modello di dati canonico per un sistema complesso.Non sono sicuro di essere d'accordo, ma è difficile dirlo, data la mancanza di esempi specifici in questa sezione.Quindi ti dirò i miei pregiudizi sull'argomento e puoi essere d'accordo o in disaccordo con me:

Spesso è un errore utilizzare un unico modello per un sistema di grandi dimensioni, a seconda delle dimensioni effettive del sistema.Tuttavia, nulla nell'Entity Framework richiede l'utilizzo di un singolo modello.D'altro canto, Entity Framework, soprattutto nella versione 1, non fa di tutto per facilitare la combinazione di più modelli.

Ora, una singola, grande applicazione per un sistema complesso può essere un errore tanto grave quanto un singolo, grande modello di dati.Pertanto non sarebbe corretto che Entity Framework semplificasse la combinazione di molti modelli minuscoli in un'unica applicazione troppo grande;ciò semplicemente sostituirebbe un problema con un altro.

D'altra parte, penso che abbia senso semplificare la costruzione di un sistema di grandi dimensioni con servizi partizionati in modo adatto al dominio problematico.Penso che i servizi dati WCF, una tecnologia separata da Entity Framework, ma che supporta molto bene Entity Framework, siano utili a questo scopo.

Penso che l'Entity Framework potrebbe, in qualche versione futura, rendere più semplice combinare due o tre modelli in un'unica applicazione quando necessario.Puoi farlo ora, ma è necessario del lavoro manuale.Ma come ho detto sopra, non vorrei "risolvere" un problema relativo a un modello di dati eccessivamente grande facilitando/incoraggiando la creazione di un'applicazione troppo grande.

LA MANCANZA DI PERSISTENZA E L'IGNORANZA FA sì che la logica aziendale sia più difficile da leggere, scrivere e modificare, causando un aumento dei costi di sviluppo e manutenzione a un ritmo esagerato:

Questa sezione fa affermazioni che trovo errate:

L'Entity Framework incoraggia l'anti-pattern del modello di dominio anemico scoraggiando l'inclusione della logica di business nelle classi di entità.

Vedi sopra.Penso che il compito dei tipi di entità sia quello di mappare lo spazio relazionale nello spazio degli oggetti.Secondo il principio di responsabilità unica, questi tipi dovrebbero dover essere modificati solo quando cambia il loro unico lavoro.Se i processi aziendali cambiano, questa è una responsabilità non correlata alla mappatura O/R.Forse le limitazioni di altri ORM impongono una barriera tecnica alla separazione di queste responsabilità.Va bene infrangere le regole quando la tecnologia lo impone, se il costo della purezza del design è eccessivo.Ma sono fortemente favorevole all’approccio dei tipi di entità privi di comportamento.

Allo stato attuale, le classi di entità EF non possono essere effettivamente sottoposte a test unitari indipendentemente dal database.

Questo è semplicemente sbagliato.Chi ha scritto questo non ha capito di cosa stessero parlando.Nessuno dei nostri test unitari tocca mai il DB e molti coinvolgono l'EF.

Per quanto riguarda la sostanza del titolo di questa sezione, c'è una modifica per EF 4.Ora è possibile avere tipi di entità che ignorano completamente la persistenza, se ciò aiuta la progettazione.Tuttavia, dalla prima versione dell'Entity Framework sulle parole, sei stato in grado di proiettare sui POCO.Quindi l’ignoranza persistente è sempre stata disponibile quando richiesto.Avere l'ignoranza della persistenza sui tipi di entità stessi consente il rilevamento delle modifiche con un oggetto che ignora la persistenza.Ciò può essere utile in alcuni casi.Ma si tratta di un sottoinsieme di casi sostanzialmente più piccolo rispetto alle false affermazioni sui test unitari, il che riduce di molto l'impatto del punto sottolineato dal documento.

ECCESSIVI CONFLITTI DI MERGE CON IL CONTROLLO DELLA SORGENTE NEGLI AMBIENTI DEL TEAM:

Unire XML è davvero così difficile?Se è così, forse si dovrebbe esaminare un nuovo strumento di unione.Non lo trovo problematico.

Tuttavia, qui c'è un vero problema, anche se, ancora una volta, è molto più limitato di quanto affermato dal documento.Piuttosto che ripetermi, ti indicherò semplicemente il mio post su quell'argomento.

In EF 4 è possibile utilizzare modelli code-first anziché modelli XML per suddividere un modello in molti file diversi.

Altri suggerimenti

Entity Framework è migliorata dalla versione 1 e questo post sul blog da un collaboratore NHibernate confronta NHibernate e Entity Framework 4.0.

EDIT:. Questa era vero, ma non è più

Come una persona che ha utilizzato sia Entity Framework e NHibernate ... vi consiglio caldamente di NHibernate. Normalmente, se un FOSS e un tecnico MS sono presenti, suggerisco il tecnico di MS, ma sono assolutamente d'accordo con quello per EF. Io uso EF4 in un giorno per giorno sul posto di lavoro, e dobbiamo creare un sacco di soluzione a causa di EF. Due anni fa ho usato EF per circa un anno, e poi ho cambiato società, e ho lavorato con EF per l'anno passato. NHibernate, 2 anni fa, è davanti a EF4.

Ecco i punti che hanno portato in su.

conflitti di unione eccessive con controllo del codice sorgente in team Ambienti:

Questo è stato in parte fissa, da quello che ho sentito. Hanno spostato i dati di posizione per il progettista per la parte inferiore del edmx, quindi non è più un problema orribile, ma comunque fastidioso. Se io e un collega sia provare a modificare l'edmx, allo stesso tempo, si tende a ottenere i conflitti di unione orribili perché l'intera parte inferiore del file viene utilizzato per memorizzare i dati di posizione delle tabelle di cui il progettista. La nostra soluzione a questo problema è quello di utilizzare file di SVN di blocco in modo da non lo facciamo doppio di modificarlo. O ignoro di blocco, e se ho un conflitto di unione, ho solo accettare le loro modifiche e rifare il mio lavoro. La maggior parte dei miei cambiamenti non sono così grandi che prendono molto tempo per ri-do. Se questo è stato l'unico problema, mi piacerebbe vivere con esso.

Se si sta utilizzando il codice-prima (in EF 4.1) questo è un non-problema.

Codice in eccesso necessari per affrontare la mancanza di Lazy Loading:

Hanno aggiunto lazy loading in 4,0.

Ma è carico preforme ancora come un pezzo di spazzatura. eager loading è lento, che è un'ottimizzazione comune quando è necessario per accelerare il vostro codice. Io corro in casi in cui devo fare 10k + chiamate al database quando Preferisco utilizzare eager loading. Abbiamo contati, e in molti casi è più veloce per effettuare chiamate di database multipli (facendo myobject.TablenameReference.Load() in un loop) a un database locale, allora è da usare .Include("Tablename"). Sì, lo so che è molto contro-intutivie, ma i numeri non mentono. Inoltre, non c'è modo di specificare lo stragety prendere, quindi non è possibile specificare di Join-fetch o meno. Quindi direi che è migliorata, ma non vicino come NHibernate.

Focus disordinato dei dati l'aspetto delle entità porta ad architetture di entità degradate:

Sì, questo è ancora vero. Ancora un buon esempio è order.Status. Ci piacerebbe davvero come quella di essere un enum, ma a causa del modo EF è stato progettato, non abbiamo altra scelta oltre a rendere una stringa. Essi possono risolvere il problema enum in futuro, ma la mancanza di controllo tra il come la mappatura è fatto tra il tavolo e l'oggetto è la vera denuncia. NHibernate permette di specificare i metodi per mappature facendo, a che fare con questo caso.

Per estendere un punto dalla risposta di Craig Stuntz, EF è stato organizzato in giro se si vuole prendere il modello di dati, e selezionare direttamente da esso. modello (IE myModel.Orders.Where(order => order.Status == "NEW").Select(order => order.Customer.FirstName, order=> order.Customer.LastName).) di EF finisce per essere davvero difficile scrivere dei test automatizzati in giro se non si vuole colpire il DB. Se si desidera un repository, in cui si chiede per un oggetto che soddisfi alcuni criteri, e restituisce l'intero oggetto, questo è ciò che NHibernate funziona meglio. (IE var order = myOrderRepository.GetByStatus(OrderStatus.New)).

Un altro problema che ho con EF è la sua totale mancanza di extensiblity. Un problema che abbiamo è che abbiamo enumerazioni per lo stato degli ordini. Ma se lo facciamo myModel.Orders.Where(order => order.Status == OrderStatus.New.ToString()), EF andrà in crash su quella query perché non conosce il metodo .ToString (). Si uglifies nostro codice molto perché non siamo in grado di aggiungere il supporto per questo. Inoltre ci sono un sacco di metodi interni, quindi abbiamo bisogno di causare un comportamento strano che accada, non possiamo farlo.

Se stai usando NHibernate, LINQ aggiunge un sacco di funzioni per NHibernate che lo rendono molto meglio. Utilizzando un modello basato su convenzioni, richiede pochissimo codice per la maggior parte delle vostre mappature. Se si utilizza un database esistente, NHibernate permette di spele convenzioni non standard cify da usare, e poi li hanno mappa verso l'alto, e tutto ciò che è facile da gestire. EF 4.0 (e non credo 4.1) non ha il supporto per una cosa del genere.

Spero che questo ti aiuta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top