Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Faules Laden mit Proxys
Die einfachste Möglichkeit, lazy-loading zu verwenden, besteht darin, das Microsoft.EntityFrameworkCore.Proxies-Paket zu installieren und es mit einem Aufruf zu UseLazyLoadingProxiesaktivieren. Beispiel:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseLazyLoadingProxies()
.UseSqlServer(myConnectionString);
Oder bei Verwendung von AddDbContext:
.AddDbContext<BloggingContext>(
b => b.UseLazyLoadingProxies()
.UseSqlServer(myConnectionString));
EF Core aktiviert dann das faule Laden für jede Navigationseigenschaft, die überschrieben werden kann, d. h. sie muss virtual sein und in einer Klasse, von der geerbt werden kann. Beispielsweise werden in den folgenden Entitäten die Navigations-Eigenschaften Post.Blog und Blog.Posts lazy geladen.
public class Blog
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
public class Post
{
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public virtual Blog Blog { get; set; }
}
Warnung
Lazy-Loading kann unnötige zusätzliche Datenbank-Transaktionen verursachen (das sogenannte N+1-Problem), und es sollte darauf geachtet werden, dies zu vermeiden. Weitere Informationen finden Sie im Abschnitt zur Leistung .
Faules Laden ohne Proxys
Lazy-Loading ohne Proxys funktioniert, indem der ILazyLoader-Dienst in eine Entität injiziert wird, wie in Entity-Typ-Konstruktoren beschrieben. Beispiel:
public class Blog
{
private ICollection<Post> _posts;
public Blog()
{
}
private Blog(ILazyLoader lazyLoader)
{
LazyLoader = lazyLoader;
}
private ILazyLoader LazyLoader { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Post> Posts
{
get => LazyLoader.Load(this, ref _posts);
set => _posts = value;
}
}
public class Post
{
private Blog _blog;
public Post()
{
}
private Post(ILazyLoader lazyLoader)
{
LazyLoader = lazyLoader;
}
private ILazyLoader LazyLoader { get; set; }
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public Blog Blog
{
get => LazyLoader.Load(this, ref _blog);
set => _blog = value;
}
}
Diese Methode erfordert nicht, dass von Entitätstypen oder Navigationseigenschaften geerbt wird, und ermöglicht es Entitätsinstanzen, die mit new erstellt wurden, nach dem Anfügen an einen Kontext lazy zu loaden. Sie erfordert jedoch einen Verweis auf den ILazyLoader Dienst, der im Microsoft.EntityFrameworkCore.Abstractions-Paket definiert ist. Dieses Paket enthält einen minimalen Satz von Typen, sodass sich je nach Paket nur geringe Auswirkungen ergeben. Um jedoch vollständig zu vermeiden, von EF Core-Paketen in den Entitätstypen abhängig zu sein, ist es möglich, die Methode ILazyLoader.Load als Delegat einzuspritzen. Beispiel:
public class Blog
{
private ICollection<Post> _posts;
public Blog()
{
}
private Blog(Action<object, string> lazyLoader)
{
LazyLoader = lazyLoader;
}
private Action<object, string> LazyLoader { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Post> Posts
{
get => LazyLoader.Load(this, ref _posts);
set => _posts = value;
}
}
public class Post
{
private Blog _blog;
public Post()
{
}
private Post(Action<object, string> lazyLoader)
{
LazyLoader = lazyLoader;
}
private Action<object, string> LazyLoader { get; set; }
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public Blog Blog
{
get => LazyLoader.Load(this, ref _blog);
set => _blog = value;
}
}
Der obige Code verwendet eine Load Erweiterungsmethode, um die Verwendung des Delegaten etwas übersichtlicher zu machen:
public static class PocoLoadingExtensions
{
public static TRelated Load<TRelated>(
this Action<object, string> loader,
object entity,
ref TRelated navigationField,
[CallerMemberName] string navigationName = null)
where TRelated : class
{
loader?.Invoke(entity, navigationName);
return navigationField;
}
}
Hinweis
Der Konstruktorparameter für den Lazy Loading-Delegaten muss "lazyLoader" genannt werden. Konfiguration für die Verwendung eines anderen Namens als dies ist für eine zukünftige Version geplant.