2013-08-20 14 views
7

Recentemente sono passato a Entity Framework 5. Ora, voglio generare le classi POCO da un database esistente e inoltre ho bisogno sia del caricamento lazy che del rilevamento delle modifiche. Quindi tutte le proprietà scalari dovrebbero essere virtuali così come le proprietà di navigazione.Come generare proxy POCO da un database esistente

L'aggiunta di un nuovo modello di dati di entità ADO.Net termina con un file .edmx e alcuni altri file .cs e .tt.

In primo luogo, mi chiedo il motivo per cui le classi POCO generate per impostazione predefinita non soddisfano i requisiti del proxy di rilevamento delle modifiche, ovvero le proprietà scalari non sono virtuali.

In secondo luogo, in che modo è possibile generare classi troppo piccole abilitate per proxy?

PS: Ho accettato la risposta di Slauma come la migliore e l'unica risposta finora, ma non sono d'accordo con la prima parte di esso. Qui è la mia tesi

Slauma parla di due problemi con delega: restrizioni e le prestazioni:

  • Circa le restrizioni sulle entità proxy-enabled: Quando le classi sono generati in DB Primo metodo per entità Framework, le regole che le classi devono seguire per abilitare i proxy di rilevamento delle modifiche non sono molto importanti perché non sono affatto restrittive. A chi importa davvero se le raccolte di navigazione sono IList o HashSet? Parlare delle restrizioni è ragionevole solo quando ci sono classi progettate perior nell'applicazione e le tabelle devono essere generate da esse.

  • Le proprietà complesse non sono supportate prima nel DB. Quindi possiamo escluderli dalla nostra discussione.

  • Chi l'perfomrance: In the addressed article e anche alcuni altri esperimenti ho studiato finora i risultati non sono molto convincenti a respingere delega a favore di snapshot. Innanzitutto, gli esperimenti sono stati condotti su un gran numero di entità a.k.a 10.000. Non è improbabile che un processo batch nell'applicazione (non nel database) funzioni su un numero elevato di entità, tuttavia vengono considerati approcci migliori come la stored procedure. In secondo luogo, in base al tipo di applicazione e alle esigenze, di solito trattiamo un numero limitato di entrate, ad esempio quando il pattern di repository è impelagato e utilizzato; non c'è differenza tra le prestazioni di proxy e snapshot. È interessante notare che nell'esperimento indirizzato, la riassegnazione dello stesso valore alle proprietà era l'unico caso in cui le prestazioni del proxy non riuscivano drammaticamente. Ma chi lo fa davvero? È molto facile stare attenti a evitare di notificare ripetutamente Change Tracker. Di nuovo, in questo caso arresti di problemi significativi quando viene trattato un numero elevato di entit.

risposta

4

In primo luogo, mi chiedo il motivo per cui le classi POCO generate per impostazione predefinita non soddisfano i requisiti di rilevamento delle modifiche delega, cioè proprietà scalari non sono virtuali.

L'utilizzo dei proxy di rilevamento delle modifiche non è consigliato come strategia di rilevamento delle modifiche predefinita. È spiegato in ulteriori dettagli in this blog post. In sostanza, il motivo principale per utilizzare i proxy di rilevamento delle modifiche - prestazioni migliori rispetto al rilevamento delle modifiche basato su snapshot - non è sempre garantito - e talvolta è ancora peggio - e l'elenco degli svantaggi è più lungo rispetto al rilevamento delle modifiche basato su snapshot.

In passato i modelli T4 che hanno generato entità POCO infatti segnato tutti proprietà - comprese le proprietà scalari - come virtual e preparato le entità per il rilevamento delle modifiche procura base. Per i motivi descritti nel blog, questo è stato modificato per i modelli più recenti, incluso DbContext Generator per EF 5, come menzionato in this comment sotto il post del blog collegato sopra. Ora, solo le proprietà di navigazione sono contrassegnate come virtual, ma non le proprietà scalari, che consente il caricamento lazy ma non è sufficiente per i proxy di rilevamento modifiche.

In secondo luogo, come è possibile generare classi piccole abilitate per proxy?

io non sono a conoscenza di qualsiasi modello T4 disponibile che avrebbe fatto questo, ma è abbastanza facile da modificare il modello predefinito per marcare anche le proprietà scalari come virtual:

  • Nel progetto si dovrebbe avere due file con estensione .tt: YourModelContainer.tt e YourModelContainer.Context.tt. Aprire il file YourModelContainer.tt.

  • In questo file troverete un metodo chiamato Property:

    public string Property(EdmProperty edmProperty) 
    { 
        return string.Format(
         CultureInfo.InvariantCulture, 
         "{0} {1} {2} {{ {3}get; {4}set; }}", 
         Accessibility.ForProperty(edmProperty), 
         _typeMapper.GetTypeName(edmProperty.TypeUsage), 
         _code.Escape(edmProperty), 
         _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 
         _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); 
    } 
    

    Cambiare la linea con ...

     Accessibility.ForProperty(edmProperty), 
    

    ... al ...

     AccessibilityAndVirtual(Accessibility.ForProperty(edmProperty)), 
    

Questo è tutto.

Solo per menzionarlo, nel caso in cui non si abbia familiarità con esso, ma esiste un secondo tipo di approccio Database-First disponibile, ovvero Reverse Engineering an existing database to a Code-First model. Questo approccio non utilizza affatto un modello T4 ma crea un modello Code-First e un contesto con mappatura API Fluent. È utile se si desidera personalizzare ed estendere le classi del modello (è anche possibile aggiungere manualmente i modificatori virtual) e procedere con il flusso di lavoro Code-First (e Code-First Migrations) in futuro per aggiornare ed evolvere lo schema del database.

+0

Grazie mille per la risposta. Non sono d'accordo con la prima parte della risposta e ho aggiornato la mia domanda per riflettere gli argomenti. Tuttavia, la seconda parte è stata molto utile. Sono a conoscenza del modello Code-First ma non mi interessa. – Alireza

+0

@Alireza: Parzialmente concordo con il tuo critico della prima parte. Sono stato un fan dei proxy di monitoraggio delle modifiche (http://stackoverflow.com/a/7112470/270591) e sono stati un risparmiatore di vita in uno dei miei progetti. Sono appena diventato un po 'più attento a usarli dopo che l'articolo di Arthur Vicker è stato pubblicato. La prima parte era più o meno solo una citazione del punto di vista del team EF per spiegare perché probabilmente hanno rimosso il modificatore 'virtuale' dalle proprietà scalari quando i nuovi modelli t4 creano i POCO. – Slauma

+1

Forse stavano ragionando come quello che hai detto, ma potevano ancora insegnare come riattivare il proxy. Questo è stato fatto da Microsoft in modo così silenzioso che si potrebbe pensare che ci sia un bug nel proxy. – Alireza