Vorab generierte Zuordnungsansichten

Bevor von Entity Framework eine Abfrage ausgeführt oder Änderungen an der Datenquelle gespeichert werden können, muss ein Satz Zuordnungsansichten für den Zugriff auf die Datenbank generiert werden. Diese Zuordnungsansichten sind eine Gruppe von Entity SQL-Anweisungen, die die Datenbank auf abstrakte Weise darstellen und Teil der Metadaten sind, die pro Anwendungsdomäne zwischengespeichert werden. Wenn Sie mehrere Instanzen des gleichen Kontexts in derselben Anwendungsdomäne erstellen, verwenden sie erneut Zuordnungsansichten aus den zwischengespeicherten Metadaten, statt sie neu zu generieren. Da das Generieren von Zuordnungsansichten einen signifikanten Teil der Gesamtkosten der Ausführung des ersten Abfrage ausmacht, können diese Zuordnungsansichten mit Entity Framework vorab generiert und dem kompilierten Projekt hinzugefügt werden. Weitere Informationen finden Sie unter Überlegungen zur Leistung (Entity Framework).

Generieren von Zuordnungsansichten mit der EF Power Tools Community Edition

Am einfachsten können Sie Ansichten vorab generieren, indem Sie die EF Power Tools Community Edition verwenden. Nachdem Sie die Power Tools installiert haben, haben Sie wie unten eine Menüoption zum Generieren von Ansichten.

  • Klicken Sie für Code First-Modelle mit der rechten Maustaste auf die Codedatei, die Ihre DbContext-Klasse enthält.
  • Klicken Sie für EF Designer-Modelle mit der rechten Maustaste auf Ihre EDMX-Datei.

generate Views

Sobald der Prozess abgeschlossen ist, verfügen Sie über eine Klasse, die der folgenden generierten Klasse ähnelt

generated Views

Wenn Sie ihre Anwendung EF jetzt ausführen, wird diese Klasse verwendet, um Ansichten nach Bedarf zu laden. Wenn ihr Modell geändert wird und Sie diese Klasse nicht erneut generieren, löst EF eine Ausnahme aus.

Generieren von Zuordnungsansichten aus Code – ab EF6

Die andere Möglichkeit zum Generieren von Ansichten besteht darin, die von EF bereitgestellten APIs zu verwenden. Bei dieser Methode haben Sie die Freiheit, die Ansichten nach Belieben zu serialisieren, aber Sie müssen die Ansichten auch selbst laden.

Hinweis

Nur ab EF6: Die in diesem Abschnitt gezeigten APIs wurden in Entity Framework 6 eingeführt. Wenn du eine frühere Version verwendest, gelten diese Informationen nicht.

Generieren von Ansichten

Die APIs zum Generieren von Ansichten befinden sich in der System.Data.Entity.Core.Mapping.StorageMappingItemCollection-Klasse. Sie können eine StorageMappingCollection für einen Kontext abrufen, indem Sie den MetadataWorkspace eines ObjectContext verwenden. Wenn Sie die neuere DbContext-API verwenden, können Sie auf diese mithilfe des folgenden IObjectContextAdapter zugreifen, in diesem Code haben wir eine Instanz Ihres abgeleiteten DbContext namens dbContext:

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

Sobald Sie über die StorageMappingItemCollection verfügen, können Sie Zugriff auf die GenerateViews- und ComputeMappingHashValue-Methoden erhalten.

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

Die erste Methode erstellt ein Wörterbuch mit einem Eintrag für jede Ansicht in der Containerzuordnung. Die zweite Methode berechnet einen Hashwert für die einzelne Containerzuordnung und wird zur Laufzeit verwendet, um zu überprüfen, ob sich das Modell seit der vorab generierten Ansicht nicht geändert hat. Außerkraftsetzungen der beiden Methoden werden für komplexe Szenarien mit mehreren Containerzuordnungen bereitgestellt.

Beim Generieren von Ansichten rufen Sie die GenerateViews-Methode auf und schreiben dann die resultierende EntitySetBase und DbMappingView aus. Außerdem müssen Sie den von der ComputeMappingHashValue-Methode generierten Hash speichern.

Laden von Ansichten

Um die von der GenerateViews-Methode generierten Ansichten zu laden, können Sie EF mit einer Klasse bereitstellen, die von der abstrakten DbMappingViewCache-Klasse erbt. DbMappingViewCache gibt zwei Methoden an, die Sie implementieren müssen:

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

Die MappingHashValue-Eigenschaft muss den von der ComputeMappingHashValue-Methode generierten Hash zurückgeben. Wenn EF nach Ansichten fragt, generiert und vergleicht er zuerst den Hashwert des Modells mit dem von dieser Eigenschaft zurückgegebenen Hash. Wenn sie nicht übereinstimmen, löst EF eine EntityCommandCompilationException-Ausnahme aus.

Die GetView-Methode akzeptiert eine EntitySetBase und Sie müssen eine DbMappingVIew zurückgeben, die die EntitätSql enthält, die für die mit der angegebenen EntitySetBase im Wörterbuch generiert wurde, das von der GenerateViews-Methode generiert wurde. Wenn EF nach einer Ansicht fragt, die Sie nicht haben, sollte GetView NULL zurückgeben.

Es folgt ein Extrakt aus dem DbMappingViewCache, der wie oben beschrieben mit den Power Tools generiert wird. In diesem Abschnitt wird eine Möglichkeit zum Speichern und Abrufen der erforderlichen EntitySql angezeigt.

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

Damit EF Ihren DbMappingViewCache verwendet, verwenden Sie dbMappingViewCacheTypeAttribute, und geben Sie den Kontext an, für den er erstellt wurde. Im folgenden Code ordnen wir den BlogContext der MyMappingViewCache-Klasse zu.

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

Für komplexere Szenarien können Cache-Instanzen von Zuordnungsansichten bereitgestellt werden, indem eine Cache-Factory einer Zuordnungsansicht angegeben wird. Dies kann durch Implementieren der abstrakten Klasse System.Data.Entity.Infrastructure.MappingViews.DbMappingViewCacheFactory erfolgen. Die Instanz der verwendeten Cache-Factory für die Zuordnungsansicht kann mithilfe der StorageMappingItemCollection.MappingViewCacheFactory-Eigenschaft abgerufen oder festgelegt werden.