Udostępnij za pośrednictwem


Wstępnie wygenerowane widoki mapowania

Zanim program Entity Framework będzie mógł wykonać zapytanie lub zapisać zmiany w źródle danych, musi wygenerować zestaw widoków mapowania w celu uzyskania dostępu do bazy danych. Te widoki mapowania są zestawem instrukcji Entity SQL, które reprezentują bazę danych w sposób abstrakcyjny i są częścią metadanych, które są buforowane dla domeny aplikacji. Jeśli utworzysz wiele wystąpień tego samego kontekstu w tej samej domenie aplikacji, będą ponownie używać widoków mapowania z buforowanych metadanych, a nie ich ponownego generowania. Ponieważ generowanie widoku mapowania jest znaczącą częścią ogólnego kosztu wykonywania pierwszego zapytania, platforma Entity Framework umożliwia wstępne generowanie widoków mapowania i uwzględnianie ich w skompilowanym projekcie. Aby uzyskać więcej informacji, zobacz Zagadnienia dotyczące wydajności (Entity Framework).

Generowanie widoków mapowania za pomocą programu EF Power Tools Community Edition

Najprostszym sposobem wstępnego generowania widoków jest użycie programu EF Power Tools Community Edition. Po zainstalowaniu narzędzi Power Tools będzie dostępna opcja menu Generuj widoki, jak pokazano poniżej.

  • W obszarze Modele Code First kliknij prawym przyciskiem myszy plik kodu zawierający klasę DbContext.
  • W przypadku modeli EF Projektant kliknij prawym przyciskiem myszy plik EDMX.

generate Views

Po zakończeniu procesu będziesz mieć klasę podobną do następującej wygenerowanej

generated Views

Teraz, gdy uruchomisz aplikację EF, użyjesz tej klasy do załadowania widoków zgodnie z potrzebami. Jeśli model ulegnie zmianie i nie wygenerujesz ponownie tej klasy, program EF zgłosi wyjątek.

Generowanie widoków mapowania z kodu — ef6 do wewnątrz

Innym sposobem generowania widoków jest użycie interfejsów API zapewnianych przez platformę EF. W przypadku korzystania z tej metody masz swobodę serializacji widoków, ale musisz również załadować widoki samodzielnie.

Uwaga

Tylko platforma EF6 — interfejsy API pokazane w tej sekcji zostały wprowadzone w programie Entity Framework 6. Jeśli używasz starszej wersji, te informacje nie mają zastosowania.

Generowanie widoków

Interfejsy API do generowania widoków znajdują się w klasie System.Data.Entity.Core.Mapping.StorageMappingItemCollection. Element StorageMappingCollection dla kontekstu można pobrać przy użyciu elementu MetadataWorkspace obiektuContext. Jeśli używasz nowszego interfejsu API DbContext, możesz uzyskać do niego dostęp przy użyciu obiektu IObjectContextAdapter, jak pokazano poniżej, w tym kodzie mamy wystąpienie pochodnego obiektu DbContext o nazwie dbContext:

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

Po utworzeniu kolekcji StorageMappingItemCollection możesz uzyskać dostęp do metod GenerateViews i ComputeMappingHashValue.

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

Pierwsza metoda tworzy słownik z wpisem dla każdego widoku w mapowaniu kontenera. Druga metoda oblicza wartość skrótu dla pojedynczego mapowania kontenera i jest używana w czasie wykonywania w celu sprawdzenia, czy model nie uległ zmianie od czasu wstępnego wygenerowania widoków. Zastąpienia tych dwóch metod są udostępniane dla złożonych scenariuszy obejmujących wiele mapowań kontenerów.

Podczas generowania widoków wywołasz metodę GenerateViews, a następnie zapisz wynikową metodę EntitySetBase i DbMappingView. Należy również przechowywać skrót wygenerowany przez metodę ComputeMappingHashValue.

Ładowanie widoków

Aby załadować widoki wygenerowane przez metodę GenerateViews, możesz udostępnić program EF z klasą dziedziczącą z klasy abstrakcyjnej DbMappingViewCache. DbMappingViewCache określa dwie metody, które należy zaimplementować:

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

Właściwość MappingHashValue musi zwrócić skrót wygenerowany przez metodę ComputeMappingHashValue. Gdy program EF będzie pytać o widoki, najpierw wygeneruje i porównuje wartość skrótu modelu z wartością skrótu zwróconą przez tę właściwość. Jeśli nie są one zgodne, program EF zgłosi wyjątek EntityCommandCompilationException.

Metoda GetView zaakceptuje metodę EntitySetBase i należy zwrócić element DbMappingVIew zawierający element EntitySql, który został wygenerowany dla elementu , który został skojarzony z daną bazą danych EntitySetBase w słowniku wygenerowanym przez metodę GenerateViews. Jeśli program EF prosi o widok, którego nie masz, polecenie GetView powinno zwrócić wartość null.

Poniżej przedstawiono wyodrębnienie z obiektu DbMappingViewCache wygenerowanego za pomocą narzędzi Power Tools zgodnie z powyższym opisem. W tym artykule widzimy jeden ze sposobów przechowywania i pobierania wymaganej jednostki 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");
    }

Aby platforma EF korzystała z obiektu DbMappingViewCache, należy dodać element DbMappingViewCacheTypeAttribute, określając kontekst, dla którego został utworzony. W poniższym kodzie skojarzymy element BlogContext z klasą MyMappingViewCache.

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

W przypadku bardziej złożonych scenariuszy wystąpienia pamięci podręcznej widoku mapowania mogą być udostępniane przez określenie fabryki pamięci podręcznej widoku mapowania. Można to zrobić, implementując abstrakcyjną klasę System.Data.Entity.Infrastructure.MappingViews.DbMappingViewCacheFactory. Wystąpienie fabryki pamięci podręcznej widoku mapowania, która jest używana, można pobrać lub ustawić przy użyciu właściwości StorageMappingItemCollection.MappingViewCacheFactoryproperty.