Partager via


Cet article a fait l'objet d'une traduction automatique.

Points de données

FAQ sur Entity Framework Code First et DbContext

Julie Lerman

 

Julie LermanCe mois-ci, je voudrais partager les réponses aux questions que me demande souvent sur le premier Code et DbContext à l'entité cadre 4.2. Afin de maximiser l'espace, je vais souligner où vous trouverez des informations détaillées afin de compléter les documents à que fournir des ressources supplémentaires.

Sera le premier Code et ajouter DbContext à la.NET Framework ?

Lol Tout d'abord le code et DbContext sera distribué séparément de la Microsoft.NET Framework version cycle, permettant à l'équipe d'Entity Framework libérer les mises à jour lorsqu'ils sont prêts, sans attendre la prochaine version officielle de la.NET Framework. Tout d'abord le code et l'API DbContext font partie de l'Assemblée EntityFramework.dll, vous pouvez ajouter à vos projets de manière dynamique à l'aide de NuGet. L'installation de l'extension NuGet dans Visual Studio vous donne le gestionnaire de paquets de bibliothèque, qui vous permet d'ajouter une référence à EntityFramework.dll à votre projet. La figure 1 montre le paquet EntityFramework (actuellement le plus populaire Télécharger dans la bibliothèque de package NuGet) dans la bibliothèque Visual Studio Package Manager.

Installing Code First and DbContext into a Project via EntityFramework.dll
Figure 1 Installation Code d'abord et DbContext dans un projet via EntityFramework.dll

Vous pouvez lire plus sur les plans de l'équipe de libération des fonctionnalités d'Entity Framework et pourquoi ils ont décidé de mettre l'accent sur l'utilisation de NuGet pour le déploiement de certains types de fonctions à l'extérieur de la.NET API dans leur post de blog octobre 2011, « Comment nous parler sur EF et son avenir Versions » (bit.ly/owoWgn).

Vous pouvez filtrer les données connexes à inclure ?

Lol La méthode Include vous permet de charger avec impatience des données lors de l'exécution de requêtes sur un modèle de données entité. Malheureusement, vous pouvez récupérer des Jeux seulement complets de données apparentées avec chargement impatient. Cela est également vrai pour le chargement de paresseux et, dans tous les cas, pour le chargement explicite. Ce cas unique : Lorsque vous chargez explicitement par le tracker changement API, vous pouvez appliquer une méthode de requête suivie d'un Where du filtre :

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

Mais pour être clair, vous ne peut pas le faire pour avide de chargement avec Include.

C'est comment inclure a travaillé depuis la première version d'Entity Framework dans le.NET Framework 3.5. Si vous souhaitez combiner désireux de chargement avec filtrage, envisagez d'utiliser des projections. Vous pouvez lire plus sur cela dans la colonne de Points de données de juin 2011, "démystifiés entité cadre stratégies : Chargement des données connexes, » à msdn.microsoft.com/magazine/hh205756. J'ai aussi écrit un blog sur le thème « Utilisation Projections et un référentiel de Fake a filtré désireux de charge, » à bit.ly/uZdnxy.

Comment est-ce que je peux utiliser des Lambdas avec Include ?

ObjectContext, est la seule manière d'utiliser Include en passant une chaîne pour représenter la propriété de navigation doit être chargé avec impatience. Par exemple, si vous avez une classe de route qui possède une propriété, arbres, qui est une ICollection <Tree>, vous serait interroger des routes avec leurs arbres comme ceci :

context.Roads.Include("Trees")

De nombreux développeurs ont créé leurs propres méthodes d'extension pour leur permettre d'utiliser une expression fortement typée au lieu de cela :

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

La capacité d'utiliser des expressions lambda à inclure maintenant intégrée à l'API DbContext. Vous trouverez un exemple dans la série de merveilleux blog de 12-partie des partie 6 de Arthur Vickers propos de l'API DbContext (bit.ly/wgI5zW). Vos tentatives pour utiliser cette fonctionnalité auraient pu être vains, mais — comme on mine. J'ai dû mettre mon ego de côté et de demander à quelqu'un de l'équipe comment obtenir le soutien de lambda. Il s'avère qu'en plus d'une référence à EntityFramework.dll, vous avez besoin une utilisation directive (ou importations pour Visual Basic) pour System.Data.Entity dans le fichier de code où vous êtes tentant d'utiliser Include avec un lambda. Si vous souhaitez étendre l'eager de chargement sur une collection de plusieurs niveaux de rapports en utilisant les lambdas, vous devez incorporer des méthodes supplémentaires Select. Par exemple, si votre classe d'arbre a une ICollection <Leaf> et vous voulez avides de charger les feuilles avec les arbres, la représentation de chaîne pourrait ressembler à ceci :

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

Cependant, le lambda s'appuie sur une logique supplémentaire pour fournir le niveau suivant de la relation. Voici la syntaxe que vous utilisez pour sélectionner les routes avec les arbres et leurs feuilles :

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

Je ne peux pas parler sur l'utilisation de multiples niveaux d'inclure sans ajouter un rappel que les relations plus que vous tentez d'eager chargement avec Include, les plus complexe et les plus dégradé devienne votre requête SQL. Je recommande toujours vivement le SQL généré par entité Framework (EF) de profilage. En fait, la colonne de Points de données de décembre 2010 montre diverses façons à la base de données de profil lors de l'utilisation de EF.

J'ai été surpris d'apprendre que si vous utilisez l'API ObjectContext, une référence à EntityFramework.dll plus un System.Data.Entity à l'aide de la directive vous indiquera également utiliser les lambdas avec inclure ici.

Ce que je dois attendre pour le.NET Framework 4.5 si je veux utiliser Code tout d'abord avec les Services de données WCF ?

Il y a deux assemblées pour créer et consommer des Services de données WCF dans le.NET Framework 4 : System.Data.Services.dll et System.Data.Services.Client.dll. Si vous essayez d'utiliser ces avec un DbContext et le premier Code des classes, ils ne travaillent hors de la boîte. La question est avec DbContext, pas le premier Code. DbContext n'existait pas lors de ces assemblées ont été construites, donc ils ne comprennent pas il. En mars 2011, Microsoft a publié une Preview CTP (Community Technology) qui contient des assemblys fixe-up (Microsoft.Data.Services.dll et Microsoft.Data.Services.Client.dll) qui sait comment travailler avec le DbContext. Tout que vous devez faire est remplacer les assemblys par défaut avec ces nouveaux assemblys et, dans vos services de données, spécifiez DataServiceProtocolVersion comme V3 plutôt que V2. Voici un exemple de ce qu'un service de données simple peut ressembler à exposer un contexte (PersonModelContext) qui hérite de DbContext :

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

Le problème avec cette solution est que les nouveaux assemblys sont seulement PCC et non à des fins de production. Vous devrez attendre la prochaine sorti Manufacturing (RTM) diffusion de Services de données pour pouvoir les utiliser en production.

Mais il est possible d'utiliser un DbContext avec.NET Framework 4 System.Data.Services assemblées. Les assemblées CTP existent juste pour vous aider à éviter d'écrire du code supplémentaire. Tout que vous devez faire est accès ObjectContext sous-jacent qui prend en charge de la DbContext et qui fournissent le service. En juillet 2010, Rowan Miller, un joueur clé de Microsoft derrière le premier Code, ce qui fut démontré dans un blog, « EF CTP4 conseils & Astuces : Service de données WCF sur DbContext"(bit.ly/c2EA0l). Ce blog a été écrit pour un aperçu au début de la DbContext, donc j'ai mis à jour son exemple fonctionne avec la version de la classe DbContext dans l'entité cadre 4.2 à l'aide de PersonModelContext, un modèle simple qui expose une DbSet pour une classe de personne. Le contexte et la classe sont indiquées à la Figure 2.

DbContext Simple de la figure 2 et de classe utilisée par un Service de données

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; }
}

Le service de données est alors défini à travailler avec un ObjectContext, plutôt que spécifiquement pour le PersonModelContext qui dérive de DbContext. Puis, en remplaçant les données du service CreateData­méthode de Source, vous pouvez exposer l'ObjectContext qui sous-tend la PersonModelContext, fournissant ainsi l'ObjectContext nécessaire au service, comme illustré à la Figure 3.

La figure 3 A données Service WCF qui utilise un DbContext avec.NET Framework 4 Service 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;
  }
}

Parce que je veux mettre l'accent sur la prestation de l'ObjectContext, c'est une vue simplifiée du code que vous ayez dans WCF Data Services.

L'inconvénient de cette approche est que vous ne pourrez pas utiliser DbContext fonctionnalités telles que la Validation (comme décrit dans ma colonne de Points de données de décembre 2011, « Manutention entité cadre Validations dans WCF Data Services, » à msdn.microsoft.com/magazine/hh580732) car le service est conçu pour fonctionner avec un ObjectContext.

Dois-je utiliser les Annotations de données ou l'API couramment pour les Configurations premiers Code ?

Je me demande cette question beaucoup. Pour comprendre la réponse, il est utile de d'abord comprendre les différences de haut niveau entre ces deux options.

Code étend tout d'abord les Annotations de données qui font déjà partie de la.NET Framework 4 System.ComponentModel.DataAnnotations espace de noms. Outre les annotations telles que ValidationAttributes (requis, StringLength, RegEx), Entity Framework ajoute des attributs pour spécifier des mappages de base de données (par exemple, la colonne, la Table et Timestamp) ou d'autres caractéristiques de modèle spécifique comme ComplexType. Les annotations sont simples à appliquer dans une classe, comme le montre la classe Person à la Figure 2.

Il y a des inconvénients possibles à l'utilisation d'Annotations de données pour configurer vos classes pour le premier Code. L'un est que vous ne serait pas un fan d'ajouter la logique liée à la persistance pour les classes de votre entreprise. Si vous avez demandé vous-même, « Quel est le nom d'une colonne de base de données viennent faire avec mon modèle de domaine? » vous ne pouvez utiliser les Annotations de données. Une autre est que ces mappages de vous obliger à référence EntityFramework.dll des assemblys qui contiennent des classes de votre entreprise. (Cela change de la.NET Framework 4.5, qui prendra possession des Annotations de données liées à EF.) Cela, aussi, peut-être pas quelque chose que vous voulez faire, surtout si vous êtes distribuer votre application à travers des niveaux. En outre, les Annotations de données premier Code n'exposer la gamme complète des configurations qui peuvent être appliquées en utilisant le premier Code. Certaines configurations, par exemple ceux spécifiant les détails particuliers pour un mappage de Table par hiérarchie (TPH), peuvent être réalisées uniquement à l'aide de l'API couramment.

Ma recommandation pour les développeurs est de choisir le style que vous aimez. Si vous préférez avoir vos configurations exprimées par l'entité cadre DbContext, utilisez l'API couramment. Si vous aimez la simplicité de l'application des attributs et il dérange pas avoir la logique le premier Code de mappage dans vos classes, utiliser des Annotations de données. Si vous avez choisi d'utiliser des Annotations de données et en croisant une configuration qui peut être exprimée qu'avec l'API couramment, puis ajouter cette configuration couramment et utiliser une combinaison des Annotations de données et des configurations couramment.

Puis-je utiliser Code tout d'abord avec une base de données existante ?

Absolument ! Bien que le comportement par défaut pour le premier Code est (utilement) créer une base de données pour vous, vous pouvez pointer vers une base de données existante avec votre propre chaîne de connexion et avoir le premier Code qui utilisent. Il y a certaines fonctionnalités internes de premier Code qui vous permettent de spécifier par programme la base de données. Par exemple, la surcharge du constructeur DbContext avec un nom de base de données ou une chaîne de connexion de base de données. Vous pouvez également spécifier et personnaliser les même types de DbContext ConnectionFactory (comme SqlConnectionFactory).

Vous aurez besoin pour s'assurer que les conventions de Code premier ainsi que les configurations que vous avez ajouté avec précision représentent comment vos classes mappent vers la base de données existante. Microsoft a travaillé sur un outil qui peut l'ingénierie inverse sur une base de données dans les classes ainsi que des configurations couramment le premier Code, qui peuvent fournir une grande longueur d'avance. Vous pouvez en apprendre plus sur cet outil dans mon post de blog de mai 2011, « Quick Look à inverser ingénieur DB dans Code première Classes » (bit.ly/lHJ2Or).

Lorsque vous spécifiez l'emplacement, éviter la validation de schéma et de l'initialisation de base de données par défaut avec le premier Code que DbContext. Vous pouvez désactiver complètement cette fonctionnalité via le premier Code d'initialisation de base de données :

Database.SetInitializer<MyContext>(null)

Vous trouverez plus sur ce sujet dans l'article MSDN Data Developer Center et de la vidéo, « Initialiseurs de base de données dans Entity Framework 4.1 » (msdn.microsoft.com/data/hh272552). Pour des exemples détaillés de travailler avec les classes ConnectionFactory et surcharges DbContext, veillez à vérifier « programmation Entity Framework : Code First » (o ' Reilly Media, 2011), un livre que j'ai coécrit avec Rowan Miller de l'équipe première de Code.

Ressources supplémentaires

Il y a beaucoup d'endroits pour en apprendre davantage sur le travail avec le premier Code et DbContext. Le blog de l'équipe Entity Framework à blogs.msdn.com/adonet est rempli d'exemples et sécurisée. Certains de l'équipe blogs de membres, tels que Rowan Miller (romiller.com) et Arthur Vickers' (blog.oneunicorn.com/author/ajcvickers), sont des endroits idéals pour vous informer sur les techniques avancées. Les forums MSDN et StackOverflow.com continuent d'être des endroits idéals pour lire les threads ou poser vos propres questions. Miller et moi récemment a écrit deux livres courts, ce qui précède » programmation Entity Framework : Code First » et « programmation d'Entity Framework : DbContext » (o ' Reilly Media, 2012). Vous pouvez obtenir en format papier ou numérique.

Il n'y a pas besoin de lutter avec essayant de comprendre des choses sur votre propre.

Julie Lerman est un MVP Microsoft,.NET mentor et consultant qui vit dans les collines du Vermont. Vous pouvez trouver sa présentation sur l'accès aux données et autre Microsoft.NETS sujets à des groupes d'utilisateurs et des conférences dans le monde entier. Elle blogs à thedatafarm.com/blog et est l'auteur de "Programming Entity Framework" (2010) et « programmation Entity Framework : Code des premiers"(2011), tous deux d'o ' Reilly Media. La suivre sur Twitter à twitter.com/julielerman.

Je remercie les experts techniques suivants d'avoir relu cet article : Mike Flasko et Diego Vega