Arbeiten mit Proxys

Beim Erstellen von Instanzen von POCO-Entitätstypen erstellt Entity Framework häufig Instanzen eines dynamisch generierten abgeleiteten Typs, der als Proxy für die Entität fungiert. Dieser Proxy setzt einige virtuelle Eigenschaften der Entität außer Kraft, um Hooks zum automatischen Ausführen von Aktionen einzufügen, wenn auf die Eigenschaft zugegriffen wird. Beispielsweise wird dieser Mechanismus verwendet, um das verzögerte Laden (Lazy Loading) von Beziehungen zu unterstützen. Die in diesem Thema dargestellten Techniken gelten jeweils für Modelle, die mit Code First und dem EF-Designer erstellt wurden.

Deaktivieren der Proxyerstellung

Manchmal ist es nützlich, zu verhindern, dass Entity Framework Proxyinstanzen erstellt. Beispielsweise ist die Serialisierung von Nicht-Proxyinstanzen wesentlich einfacher als die Serialisierung von Proxyinstanzen. Die Proxyerstellung kann deaktiviert werden, indem das ProxyCreationEnabled-Flag gelöscht wird. Ein Ort, an dem Sie dies tun können, ist der Konstruktor Ihres Kontexts. Beispiel:

public class BloggingContext : DbContext
{
    public BloggingContext()
    {
        this.Configuration.ProxyCreationEnabled = false;
    }  

    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
}

Beachten Sie, dass EF keine Proxys für Typen erstellt, bei denen für den Proxy nichts zu tun ist. Dies bedeutet, dass Sie Proxys auch vermeiden können, indem Sie Typen haben, die versiegelt sind und/oder keine virtuellen Eigenschaften aufweisen.

Explizites Erstellen einer Instanz eines Proxys

Eine Proxyinstanz wird nicht erstellt, wenn Sie eine Instanz einer Entität mithilfe des neuen Operators erstellen. Dies stellt unter Umständen kein Problem dar, aber wenn Sie eine Proxyinstanz erstellen müssen (z. B. damit das verzögerte Laden oder die Proxy-Änderungsnachverfolgung funktioniert), können Sie dies mithilfe der Create-Methode von DbSet tun. Beispiel:

using (var context = new BloggingContext())
{
    var blog = context.Blogs.Create();
}

Die generische Version von Create kann verwendet werden, wenn Sie eine Instanz eines abgeleiteten Entitätstyps erstellen möchten. Beispiel:

using (var context = new BloggingContext())
{
    var admin = context.Users.Create<Administrator>();
}

Beachten Sie, dass die Create-Methode die erstellte Entität nicht dem Kontext hinzufügt oder an diesen anfügt.

Beachten Sie, dass die Create-Methode nur eine Instanz des Entitätstyps selbst erstellt, wenn das Erstellen eines Proxytyps für die Entität keinen Wert hätte, da sie nichts tun würde. Wenn beispielsweise der Entitätstyp versiegelt ist und/oder keine virtuellen Eigenschaften aufweist, erstellt Create nur eine Instanz des Entitätstyps.

Abrufen des tatsächlichen Entitätstyps aus einem Proxytyp

Proxytypen weisen Namen auf, die ungefähr wie folgt aussehen:

System.Data.Entity.DynamicProxies.Blog_5E43C6C196972BF0754973E48C9C941092D86818CD94005E9A759B70BF6E48E6

Sie können den Entitätstyp für diesen Proxytyp mithilfe der GetObjectType-Methode aus ObjectContext finden. Beispiel:

using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);
    var entityType = ObjectContext.GetObjectType(blog.GetType());
}

Beachten Sie, dass der Entitätstyp weiterhin zurückgegeben wird, wenn der an GetObjectType übergebene Typ eine Instanz eines Entitätstyps ist, der kein Proxytyp ist. Dies bedeutet, dass Sie diese Methode immer verwenden können, um den tatsächlichen Entitätstyp ohne eine andere Überprüfung abzurufen, um festzustellen, ob der Typ ein Proxytyp ist oder nicht.