Vues de mappage pré-générées
Avant que Entity Framework puisse exécuter une requête ou enregistrer des modifications apportées à la source de données, il doit générer un ensemble d’affichages du mappage pour accéder à la base de données. Ces vues de mappage sont un ensemble d’instructions Entity SQL qui représentent la base de données de manière abstraite et font partie des métadonnées mises en cache par domaine d’application. Si vous créez plusieurs instances du même contexte dans le même domaine d'application, elles réutiliseront les vues de mappage des métadonnées mises en cache au lieu de les régénérer. Étant donné que le mappage de la génération de vues constitue une partie significative du coût total de l'exécution d'une première requête, l’entity Framework vous permet de pré-générer ces vues de mappage et de les inclure dans le projet compilé. Pour plus d’informations, consultez Considérations sur les performances (Entity Framework)
Génération de vues de mappage avec EF Power Tools Community Edition
Le moyen le plus simple de pré-générér les vues consiste à utiliser la EF Power Tools Community Edition. Une fois que Power Tools est installé, vous disposez d’une option de menu pour générer des vues, comme indiqué ci-dessous.
- Pour Code First modèles, cliquez avec le bouton droit sur le fichier de code qui contient votre classe DbContext.
- Pour modèles EF Designer cliquez avec le bouton droit sur votre fichier EDMX.
Une fois le processus terminé, vous aurez une classe similaire à la suivante générée
Maintenant, lorsque vous exécutez votre application EF, utilisez cette classe pour charger des vues en fonction des besoins. Si votre modèle change et que vous ne régénérez pas cette classe, EF lève une exception.
Génération de vues de mappage à partir de code : EF6 et au-delà
L’autre façon de générer des vues consiste à utiliser les API que EF fournit. Lorsque vous utilisez cette méthode, vous avez la liberté de sérialiser les vues comme vous le souhaitez, mais vous devez également charger les vues vous-même.
Remarque
EF6 uniquement : Les API indiquées dans cette section ont été introduites dans Entity Framework 6. Si vous utilisez une version antérieure, ces informations ne s’appliquent pas.
Génération de vues
Les API permettant de générer des vues se trouvent sur la classe System.Data.Entity.Core.Mapping.StorageMappingItemCollection. Vous pouvez récupérer un StorageMappingCollection pour un contexte à l’aide de MetadataWorkspace d’un ObjectContext. Si vous utilisez l’API DbContext la plus récente, vous pouvez y accéder à l’aide de iObjectContextAdapter comme ci-dessous, dans ce code, nous avons une instance de votre dbContext dérivé appelé dbContext :
var objectContext = ((IObjectContextAdapter) dbContext).ObjectContext;
var mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace
.GetItemCollection(DataSpace.CSSpace);
Une fois que vous disposez de StorageMappingItemCollection, vous pouvez accéder aux méthodes GenerateViews et ComputeMappingHashValue.
public Dictionary<EntitySetBase, DbMappingView> GenerateViews(IList<EdmSchemaError> errors)
public string ComputeMappingHashValue()
La première méthode crée un dictionnaire avec une entrée pour chaque vue dans le mappage de conteneur. La deuxième méthode calcule une valeur de hachage pour le mappage de conteneur unique et est utilisée au moment de l’exécution pour vérifier que le modèle n’a pas changé depuis la pré-génération des vues. Les remplacements des deux méthodes sont fournis pour des scénarios complexes impliquant plusieurs mappages de conteneurs.
Lorsque vous générez des vues, vous appelez la méthode GenerateViews, puis écrivez l’EntitySetBase et DbMappingView résultants. Vous devez également stocker le hachage généré par la méthode ComputeMappingHashValue.
Chargement des vues
Pour charger les vues générées par la méthode GenerateViews, vous pouvez fournir à EF une classe qui hérite de la classe abstraite DbMappingViewCache. DbMappingViewCache spécifie deux méthodes que vous devez implémenter :
public abstract string MappingHashValue { get; }
public abstract DbMappingView GetView(EntitySetBase extent);
La propriété MappingHashValue doit retourner le hachage généré par la méthode ComputeMappingHashValue. Quand EF va demander des vues, elle va d’abord générer et comparer la valeur de hachage du modèle avec le hachage retourné par cette propriété. S’ils ne correspondent pas, EF lève une exception EntityCommandCompilationException.
La méthode GetView accepte une EntitySetBase et vous devez retourner un DbMappingVIew contenant l’EntitySql qui a été généré pour celui-ci a été associé à EntitySetBase donné dans le dictionnaire généré par la méthode GenerateViews. Si EF demande une vue que vous n’avez pas, GetView doit retourner null.
Voici un extrait de DbMappingViewCache généré avec Power Tools comme décrit ci-dessus. Dans ce cas, nous voyons un moyen de stocker et de récupérer EntitySql requis.
public override string MappingHashValue
{
get { return "a0b843f03dd29abee99789e190a6fb70ce8e93dc97945d437d9a58fb8e2afd2e"; }
}
public override DbMappingView GetView(EntitySetBase extent)
{
if (extent == null)
{
throw new ArgumentNullException("extent");
}
var extentName = extent.EntityContainer.Name + "." + extent.Name;
if (extentName == "BlogContext.Blogs")
{
return GetView2();
}
if (extentName == "BlogContext.Posts")
{
return GetView3();
}
return null;
}
private static DbMappingView GetView2()
{
return new DbMappingView(@"
SELECT VALUE -- Constructing Blogs
[BlogApp.Models.Blog](T1.Blog_BlogId, T1.Blog_Test, T1.Blog_title, T1.Blog_Active, T1.Blog_SomeDecimal)
FROM (
SELECT
T.BlogId AS Blog_BlogId,
T.Test AS Blog_Test,
T.title AS Blog_title,
T.Active AS Blog_Active,
T.SomeDecimal AS Blog_SomeDecimal,
True AS _from0
FROM CodeFirstDatabase.Blog AS T
) AS T1");
}
Pour qu’EF utilise votre DbMappingViewCache, vous ajoutez l’objet DbMappingViewCacheTypeAttribute, en spécifiant le contexte pour lequel il a été créé. Dans le code ci-dessous, nous allons associer le BlogContext à la classe MyMappingViewCache.
[assembly: DbMappingViewCacheType(typeof(BlogContext), typeof(MyMappingViewCache))]
Pour les scénarios plus complexes, les instances de cache de vue de mappage peuvent être fournies en spécifiant une fabrique de cache de vue de mappage. Pour ce faire, implémentez la classe abstraite System.Data.Entity.Infrastructure.MappingViews.DbMappingViewCacheFactory. L’instance de la fabrique de cache de vue de mappage utilisée peut être récupérée ou définie à l’aide de StorageMappingItemCollection.MappingViewCacheFactoryproperty.