Předgenerovaná zobrazení mapování

Než entity Framework může spustit dotaz nebo uložit změny ve zdroji dat, musí vygenerovat sadu zobrazení mapování pro přístup k databázi. Tato zobrazení mapování jsou sada příkazů Entity SQL, které představují databázi abstraktním způsobem a jsou součástí metadat, která jsou uložena v mezipaměti pro každou doménu aplikace. Pokud ve stejné doméně aplikace vytvoříte více instancí stejného kontextu, budou znovu používat zobrazení mapování z metadat uložených v mezipaměti a nebudou je znovu vygenerovat. Vzhledem k tomu, že generování zobrazení mapování je významnou součástí celkových nákladů na provedení prvního dotazu, rozhraní Entity Framework umožňuje předem vygenerovat zobrazení mapování a zahrnout je do zkompilovaného projektu. Další informace naleznete v tématu Důležité informace o výkonu (Entity Framework).

Generování zobrazení mapování pomocí EF Power Tools Community Edition

Nejjednodušší způsob, jak předem generovat zobrazení, je použít EF Power Tools Community Edition. Jakmile máte nainstalované Nástroje Power Tools, budete mít možnost nabídky Generovat zobrazení, jak je uvedeno níže.

  • V případě modelů Code First klikněte pravým tlačítkem myši na soubor kódu, který obsahuje vaši DbContext třídy.
  • V případě modelů EF Designer klikněte pravým tlačítkem myši na váš soubor EDMX.

generate Views

Po dokončení procesu budete mít třídu podobnou následující vygenerované.

generated Views

Když teď spustíte aplikaci EF, použije tuto třídu k načtení zobrazení podle potřeby. Pokud se váš model změní a tuto třídu znovu nevygenerujete, ef vyvolá výjimku.

Generování zobrazení mapování z kódu – EF6 a vyšší

Dalším způsobem, jak generovat zobrazení, je použít rozhraní API, která ef poskytuje. Při použití této metody máte svobodu serializovat zobrazení, ale chcete, ale musíte také načíst zobrazení sami.

Poznámka

Pouze EF6 – Rozhraní API zobrazená v této části byla zavedena v Entity Frameworku 6. Pokud používáte starší verzi, tyto informace se nevztahují.

Generování zobrazení

Rozhraní API pro generování zobrazení jsou ve třídě System.Data.Entity.Core.Mapping.StorageMappingItemCollection. StorageMappingCollection pro kontext můžete načíst pomocí MetadataWorkspace ObjectContext. Pokud používáte novější rozhraní DBContext API, můžete k němu přistupovat pomocí objektu IObjectContextAdapter, jak je znázorněno níže, v tomto kódu máme instanci odvozeného dbContext s názvem dbContext:

    var objectContext = ((IObjectContextAdapter) dbContext).ObjectContext;
    var  mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace
                                                                        .GetItemCollection(DataSpace.CSSpace);

Jakmile budete mít StorageMappingItemCollection pak můžete získat přístup k GenerateViews a ComputeMappingHashValue metody.

    public Dictionary<EntitySetBase, DbMappingView> GenerateViews(IList<EdmSchemaError> errors)
    public string ComputeMappingHashValue()

První metoda vytvoří slovník s položkou pro každé zobrazení v mapování kontejneru. Druhá metoda vypočítá hodnotu hash pro mapování jednoho kontejneru a používá se za běhu k ověření, že se model od předgenerování zobrazení nezměnil. Přepsání těchto dvou metod jsou poskytována pro složité scénáře zahrnující více mapování kontejnerů.

Při generování zobrazení budete volat GenerateViews metoda a pak zapsat výsledný EntitySetBase a DbMappingView. Budete také muset uložit hodnotu hash vygenerovanou metodou ComputeMappingHashValue.

Načítání zobrazení

Pokud chcete načíst zobrazení vygenerovaná metodou GenerateViews, můžete ef poskytnout třídu, která dědí z DbMappingViewCache abstraktní třídy. DbMappingViewCache určuje dvě metody, které musíte implementovat:

    public abstract string MappingHashValue { get; }
    public abstract DbMappingView GetView(EntitySetBase extent);

Vlastnost MappingHashValue musí vrátit hodnotu hash vygenerovanou výpočetní metodou ComputeMappingHashValue. Když EF požádá o zobrazení, nejprve vygeneruje a porovná hodnotu hash modelu s hodnotou hash vrácenou touto vlastností. Pokud se neshodují, ef vyvolá výjimku EntityCommandCompilationException.

GetView metoda přijme EntitySetBase a potřebujete vrátit DbMappingVIew obsahující EntitySql, který byl vygenerován pro danou EntitySetBase ve slovníku generovaném GenerateViews metoda. Pokud EF požádá o zobrazení, které nemáte, getView by měl vrátit hodnotu null.

Následuje extrahování z DbMappingViewCache vygenerované pomocí Nástrojů Power Tools, jak je popsáno výše, v něm vidíme jeden způsob, jak uložit a načíst požadované EntitySql.

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

Pokud chcete, aby EF používal vaši dbMappingViewCache, kterou přidáte, použijte DbMappingViewCacheTypeAttribute a zadejte kontext, pro který byl vytvořen. V následujícím kódu přidružíme BlogContext ke třídě MyMappingViewCache.

    [assembly: DbMappingViewCacheType(typeof(BlogContext), typeof(MyMappingViewCache))]

V případě složitějších scénářů je možné instance mezipaměti zobrazení mapování poskytnout zadáním objektu pro vytváření mezipaměti zobrazení mapování. To lze provést implementací abstraktní třídy System.Data.Entity.Infrastructure.MappingViews.DbMappingViewCacheFactory. Instance objektu pro vytváření mezipaměti zobrazení mapování, která se používá, lze načíst nebo nastavit pomocí StorageMappingItemCollection.MappingViewCacheFactoryproperty.