Il presente articolo è stato tradotto automaticamente.

I punti dati

Domande frequenti su Entity Framework Code First e DbContext

Julie Lerman

 

Julie LermanQuesto mese, piacerebbe condividere le risposte alle domande che sono frequenti su codice prima e DbContext in Entity Framework 4.2. Per ottimizzare lo spazio, potrai scegliere risorse aggiuntive, dove si possono trovare informazioni dettagliate per integrare il materiale che forniscono.

Codificherà prima e DbContext essere aggiunti i.NET Framework?

Lol Codice prima e DbContext saranno distribuite separatamente da Microsoft.NET Framework rilasciare il ciclo, permettendo che il team di Entity Framework rilasciare gli aggiornamenti quando sono pronti, senza attendere il prossimo rilascio ufficiale della.NET Framework. In primo luogo il codice e l'API DbContext fanno parte dell'Assemblea EntityFramework.dll, che può aggiungere ai vostri progetti dinamicamente utilizzando NuGet. Installare l'estensione NuGet in Visual Studio ti dà la libreria Package Manager, che consente di aggiungere un riferimento a EntityFramework.dll al progetto. La figura 1 mostra il pacchetto EntityFramework (attualmente il download più popolare nella libreria pacchetto NuGet) in Visual Studio Library Package Manager.

Installing Code First and DbContext into a Project via EntityFramework.dll
Figura 1 l'installazione di codice prima e DbContext in un progetto tramite EntityFramework.dll

Si può leggere di più circa i piani della squadra per liberare le caratteristiche di Entity Framework e perché hanno deciso di concentrarsi sull'uso di NuGet per la distribuzione di alcuni tipi di caratteristiche di fuori della.NET API nel loro ottobre 2011 blog post, "Come noi parlare circa EF e il suo futuro versioni" (bit.ly/owoWgn).

È possibile filtrare dati correlati con Includi?

Lol Il metodo Include consente di caricare con impazienza i dati correlati durante l'esecuzione di query su un Entity Data Model. Purtroppo, è possibile recuperare solo completi della dati correlati con il caricamento ansioso. Questo vale anche per caricamento lazy e, nel caso di tutti tranne uno, per caricamento esplicito. Quel caso singolo: Quando si carica in modo esplicito attraverso il cambiamento tracker API, è possibile applicare un metodo di Query, seguito da un cui filtrare:

context.Entry(personInstance)
  .Collection(p => p.Aliases)
  .Query()
  .Where(a=>a.FirstName == "Natasha")
  .Load();

Ma per essere chiari, non può farlo per desideroso di caricamento con Include.

Questo è come Includi ha lavorato fin dalla prima versione di Entity Framework nella.NET Framework 3.5. Se si desidera combinare desideroso caricamento con filtraggio, considerare l'utilizzo di proiezioni. Si può leggere di più su questo nella colonna punti dati giugno 2011, "Demystifying Entity Framework strategie: Caricamento dati correlati,"a msdn.microsoft.com/magazine/hh205756. Ho anche scritto un post sul blog sul tema, "Uso proiezioni e un Repository di Fake un filtrato desiderosi carico," a bit.ly/uZdnxy.

Come posso usare le espressioni lambda con Includi?

Con ObjectContext, l'unico modo per utilizzare Include è attraverso il passaggio di una stringa per rappresentare la proprietà di navigazione deve essere caricato con impazienza. Ad esempio se si dispone di una classe di strada che dispone di una proprietà, alberi, che è oggetto ICollection <Tree>, sarebbe query per le strade con i loro alberi come questo:

context.Roads.Include("Trees")

Molti sviluppatori hanno creato i propri metodi di estensione per consentire loro di utilizzare un'espressione fortemente tipizzata invece:

context.Roads.Include(r => r.Trees)

La capacità di utilizzare le espressioni lambda con Include ora è costruita nell'API DbContext. Troverai un esempio nella serie blog meraviglioso 12-parte Diana parte 6 di Arthur Vickers sull'API DbContext (bit.ly/wgI5zW). Vostri tentativi di utilizzare questa funzionalità potrebbero essere stato un successo, tuttavia — come erano miei. Ho dovuto mettere da parte il mio ego e chiedere a qualcuno del team come ottenere il sostegno di lambda. Si scopre che oltre a un riferimento a EntityFramework.dll, bisogno di un tramite direttiva (o le importazioni in Visual Basic) per System.Data.Entity nel file di codice dove si sta tentando di utilizzare Include con un lambda. Se volete espandere il desideroso di carico su un insieme di livelli multipli di relazioni utilizzando le espressioni lambda, devi includere metodi Select supplementare. Ad esempio, se la classe albero ha un ICollection <Leaf> e si desidera desiderosi di caricare le foglie insieme con gli alberi, la rappresentazione di stringa sarebbe simile a questo:

context.Roads.Include("Trees.Leaves")

Tuttavia, la lambda si basa sulla logica aggiuntiva per fornire il livello successivo del rapporto. Ecco la sintassi che utilizzerebbe per selezionare le strade con gli alberi e le foglie:

context.Roads.Include(r => r.Trees.Select(t => t.Leaves))

Non posso parlare con più livelli di includono senza l'aggiunta di un promemoria che le relazioni più che si tenta di desideroso caricano con Include, più complessa e degradate potrebbe diventare la query SQL. Sempre mi raccomando profilatura SQL generato da Entity Framework (EF). In realtà, la colonna di dicembre 2010 punti dati dimostra vari modi per profilare il database quando si utilizza EF.

Ha sorpreso di apprendere che se si sta utilizzando l'API di ObjectContext, un riferimento al EntityFramework.dll più un System.Data.Entity direttiva using li lascerà usare espressioni lambda con Includi qui, pure.

Che devo aspettare il.NET Framework 4.5 se voglio utilizzare codice prima con WCF Data Services?

Sono presenti due assembly per la creazione e l'utilizzo di WCF Data Services nella.NET Framework 4: System.Data.Services.dll e System.Data.Services.Client.dll. Se si tenta di utilizzare queste classi di DbContext e il primo codice, essi non funziona out of the box. Il problema è con DbContext, non il primo codice. DbContext non esistono quando tali assembly sono stati costruiti, quindi non capiscono. Nel marzo 2011, Microsoft ha rilasciato una Preview CTP (Community Technology) che conteneva fisso-up assembly (Microsoft.Data.Services.dll e Microsoft.Data.Services.Client.dll) che sanno come lavorare con il DbContext. Così tutto quello che dovete fare è sostituire gli assembly predefiniti con questi nuovi assembly e, nei vostri servizi dati, specificare DataServiceProtocolVersion come V3 anziché V2. Ecco un esempio di come un contesto (PersonModelContext) che eredita da DbContext l'esposizione può apparire un servizio dati semplici:

public class DataService : DataService<PersonModelContext>
  {
    public static void InitializeService(DataServiceConfiguration config)
    {
      config.SetEntitySetAccessRule("People", EntitySetRights.All);
      config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
    }
}

Il problema con questa soluzione è che il nuovo assembly sono solo CTP e non a fini di produzione. Si dovrà attendere il prossimo ha liberato alla release Manufacturing (RTM) di servizi dati per essere in grado di utilizzarli in produzione.

Ma è possibile utilizzare un DbContext con.NET Framework 4 System.Data.Services assembly. Gli assembly CTP esistono solo per aiutare a evitare di scrivere del codice aggiuntivo. Tutto quello che dovete fare è l'accesso ObjectContext sottostante che supporta il DbContext e che forniscono al servizio. Nel luglio 2010, Rowan Miller, un giocatore chiave di Microsoft dietro il primo codice, questo ha dimostrato in un post di blog, "EF CTP4 Tips & Trucchi: Servizio WCF Data su DbContext"(bit.ly/c2EA0l). Che blog è stato scritto per un'anteprima precoce della DbContext, così io ho aggiornato il suo esempio di lavorare con la versione della classe DbContext Entity Framework 4.2 utilizzando PersonModelContext, un semplice modello che espone uno DbSet per una classe di persona. Il contesto e la classe sono mostrati nella figura 2.

Figura 2 semplici DbContext e classe utilizzata da un servizio dati

public class PersonModelContext : DbContext
{
  public DbSet<Person> People { get; set; }
}
public class Person
{
  public int PersonId { get; set; }
  [MaxLength(10)]
  public string IdentityCardNumber { get; set; }
  public string FirstName { get; set; }
  [Required]
  public string LastName { get; set; }
}

Il servizio dati è quindi definito a lavorare con un ObjectContext, piuttosto che specificamente per il PersonModelContext che deriva da DbContext. Poi, eseguendo l'override dei dati del servizio CreateData­metodo di origine, è possibile esporre ObjectContext che soggiace PersonModelContext, fornendo in ObjectContext necessari al servizio, come illustrato nella figura 3.

Figura 3 A dati servizio WCF che utilizza un DbContext con.NET Framework 4 servizio API

public class DataService : DataService<ObjectContext>
{
  public static void InitializeService(DataServiceConfiguration config)
  {
    config.SetEntitySetAccessRule("People", EntitySetRights.All);
    config.DataServiceBehavior.MaxProtocolVersion =
      DataServiceProtocolVersion.V2;
  }
  protected override ObjectContext CreateDataSource()
  {
    var dbContext = new PersonModelContext();
    var oContext = ((IObjectContextAdapter)dbContext).ObjectContext;
    return oContext;
  }
}

Perché ho voglia di fuoco sulla fornitura di ObjectContext, questa è una visione semplificata del codice che avete in WCF Data Services.

Lo svantaggio di questo approccio è che non sarà in grado di utilizzare le funzionalità di DbContext quali la convalida (come descritto nel mio articolo di dicembre 2011 punti dati, "Handling Entity Framework le convalide in WCF Data Services," a msdn.microsoft.com/magazine/hh580732) poiché il servizio è stato progettato per funzionare con un ObjectContext.

Dovrei usare le annotazioni di dati o l'API fluente per configurazioni primi codice?

Ottengo chiesto questa domanda un sacco. Per capire la risposta, è utile prima di capire le differenze di alto livello tra queste due opzioni.

Il codice prima estende le annotazioni di dati che sono già parte della.NET Framework 4 System.ComponentModel.DataAnnotations dello spazio dei nomi. Oltre alle annotazioni, come ValidationAttributes (obbligatorio, StringLength, RegEx), Entity Framework aggiunge gli attributi per specificare il mapping del database (ad esempio, colonna, tavolo e Timestamp) o altre caratteristiche specifiche del modello come ComplexType. Le annotazioni sono semplici da applicare in una classe, come dimostra la classe Person nella figura 2.

Ci sono alcuni possibili inconvenienti a configurare le classi per il primo codice utilizzando le annotazioni di dati. Uno è che potrebbe non essere un fan di aggiungere logica di persistenza per le classi di attività. Se avete chiesto voi stessi, "Che cosa se il nome di una colonna di database ha a che fare con il modello di dominio?" si potrebbe non voler utilizzare le annotazioni di dati. Un altro è che questi mapping si richiedono per fare riferimento a EntityFramework.dll da un assembly che contiene le classi di attività. (Questo cambia come della.NET Framework 4.5, che avrà la titolarità delle annotazioni di dati correlati EF.) Che, troppo, potrebbe non essere qualcosa che si desidera fare, soprattutto se stai si distribuisce l'applicazione su livelli. Inoltre, le annotazioni di dati prima di codice non esporre la scaletta completa di configurazioni che possono essere applicati utilizzando codice prima. Alcune configurazioni, ad esempio quelli specificando particolari per il mapping di una tabella Per gerarchia (TPH), possono essere raggiunto solo utilizzando l'API fluente.

La mia raccomandazione agli sviluppatori è quello di scegliere lo stile che piace. Se si preferisce avere le configurazioni espresse dall'Entity Framework DbContext, quindi utilizzare l'API fluente. Se ti piace la semplicità di applicazione di attributi e non dispiacerebbe avere la logica di mappatura primo codice nelle classi, utilizzare le annotazioni di dati. Se hai scelto di utilizzare le annotazioni di dati e venire attraverso una configurazione che può essere espresso solo con l'API fluente, poi aggiungere che la configurazione fluente e utilizzano una combinazione di configurazioni fluente e le annotazioni di dati.

Posso usare codice prima con un Database esistente?

Assolutamente! Anche se il comportamento predefinito per il primo codice è (utilmente) creare un database per te, puoi puntare a un database esistente con il proprio stringa di connessione e hanno codice prima di usare quello. Ci sono alcune caratteristiche interne del codice prima che consentono di specificare a livello di programmazione il database pure. Ad esempio, è possibile eseguire l'overload del costruttore di DbContext con un nome di database o una stringa di connessione al database. Puoi anche specificare e personalizzare anche i tipi di DbContext ConnectionFactory (come SqlConnectionFactory).

Sarà necessario assicurarsi che il primo codice convenzioni più eventuali configurazioni che hai aggiunto con precisione rappresentano come le classi verranno eseguito il mapping a un database esistente. Microsoft ha lavorato su uno strumento che può decodificare un database in classi più configurazioni fluente primo codice, che possono fornire un grande vantaggio. Potete saperne di più su questo strumento nel mio post di blog di maggio 2011, "Quick Look at Reverse Engineer DB in codice prima classi" (bit.ly/lHJ2Or).

Quando si specifica la posizione, evitare la convalida dello schema e inizializzazione database che DbContext fa di default con il primo codice. È possibile disattivare completamente questa funzionalità tramite codice prima inizializzazione database:

Database.SetInitializer<MyContext>(null)

Troverete più su questo argomento nel articolo Developer Center di MSDN dati e video, "Database Initializers in Entity Framework 4.1" (msdn.microsoft.com/data/hh272552). Per esempi dettagliati di lavorare con le classi ConnectionFactory e DbContext gli overload, assicuratevi di check-out "Programming Entity Framework: Codice prima"(o ' Reilly Media, 2011), un libro che coautore con Rowan Miller dal codice prima squadra.

Risorse supplementari

Ci sono molti posti per apprendere lavorando con codice prima e DbContext. Il blog del team di Entity Framework in blogs.msdn.com/adonet è piena di esempi e Walk-through. Alcuni team di membri blog, come ad esempio Rowan Miller (romiller.com) e 'Arthur Vickers (blog.oneunicorn.com/author/ajcvickers), sono luoghi ideali per leggere su tecniche avanzate. I forum MSDN e StackOverflow.com continuano ad essere luoghi ideali per leggere il thread o chiedere vostre proprie domande. Miller e ho recentemente scritto due libri brevi, il suddetto "Programming Entity Framework: Codice prima"e" programmazione Entity Framework: DbContext"(o ' Reilly Media, 2012). È possibile ottenere questi in formato digitale o stampa.

Non non c'è alcuna necessità di lottare con cercando di capire le cose fuori sul proprio.

Julie Lerman è un Microsoft MVP,.Consulente che vive nelle colline del Vermont e mentore NET. È possibile trovare la sua presentazione sull'accesso ai dati e altri Microsoft.NET argomenti a gruppi di utenti e conferenze in tutto il mondo. Blog di lei a /blog ed è l'autore di "Programming Entity Framework" (2010) e "Programming Entity Framework: Codice prima"(2011), entrambi da o ' Reilly Media. Lei seguire su Twitter a twitter.com/julielerman.

Grazie ai seguenti esperti tecnici per la revisione di questo articolo: Mike Flasko e Diego Vega