Wann muss ich in EF aufnehmen? Wird in der Projektion nicht benötigt?

entity-framework entity-framework-core

Frage

Ich habe Folgendes in Entity Framework Core:

public class Book {
  public Int32 Id { get; set; }
  public String Title { get; set; }
  public virtual Theme Theme { get; set; }
}

public class Theme {
  public Int32 Id { get; set; }
  public String Name { get; set; }
  public Byte[] Illustration { get; set; }
  public virtual ICollection<Ebook> Ebooks { get; set; }
}

Und ich habe die folgende linq Abfrage:

List<BookModel> books = await context.Books.Select(x =>
  new BookModel {
    Id = x.Id,
    Name = x.Name,
    Theme = new ThemeModel {
      Id = x.Theme.Id,
      Name = x.Theme.Name
    }
   }).ToListAsync();

Ich musste das Theme nicht hinzufügen , um dies zu ermöglichen, zB:

List<BookModel> books = await context.Books.Include(x => x.Theme).Select(x => ...

Wann muss ich Include in Entity Framework verwenden?

AKTUALISIEREN

Ich habe eine Spalte vom Typ Byte [] Illustration in Theme hinzugefügt. In meiner Projektion schließe ich diese Spalte nicht ein, also wird sie geladen, wenn ich Include verwende? Oder wird nie geladen, es sei denn, ich habe es in der Projektion?

Akzeptierte Antwort

Sie haben Include nicht benötigt, weil Sie innerhalb des EF-Kontexts gearbeitet haben. Wenn Sie Theme innerhalb des anonymen Objekts referenzieren, das Sie erstellen, das kein Lazy Loading verwendet, wird EF angewiesen, eine Verknüpfung zu erstellen.

Wenn Sie eine Liste von Büchern zurückgeben und die Themen nicht einschließen, werden Sie beim Versuch, das Thema zu erhalten, feststellen, dass es null ist. Wenn die EF-Verbindung offen ist und Sie Lazy Loading haben, wird es an die DB gehen und es für Sie greifen. Aber, wenn die Verbindung nicht geöffnet ist, dann müssen Sie es explizit erhalten.

Wenn Sie dagegen Include verwenden, erhalten Sie die Daten sofort. Unter der Haube wird es ein JOIN zur notwendigen Tabelle machen und die Daten genau dort bekommen.

Sie können die SQL-Abfrage überprüfen, die EF für Sie generiert und die Dinge für Sie klarer macht. Sie sehen nur eine SQL-Abfrage.


Beliebte Antwort

Wenn Sie ein Include , wird es als Teil der ursprünglichen Abfrage geladen, wodurch es größer wird.

Wenn Sie das untergeordnete Element in der Abfrage nicht Include oder auf andere Weise nicht darauf verweisen, ist das anfängliche Ergebnisset zwar kleiner, aber jedes untergeordnete Objekt, auf das Sie später verweisen, wird durch eine neue Anforderung in der Datenbank langsam geladen.

Wenn Sie 1000 Benutzer in einer Anfrage durchlaufen und dann jeweils 10 Fotos anfordern, werden 1001 Datenbankanforderungen erstellt, wenn Sie das Kind nicht Include ...

Lazy Loading erfordert auch, dass der Kontext nicht entsorgt wurde. Immer eine unangenehme Überraschung, wenn Sie beispielsweise eine Entity an eine View für UI-Rendering übergeben.

update Versuchen Sie dies zum Beispiel und sehen Sie es scheitern:

var book = await context.Books.First();
var theme = book.Theme;

Dann versuchen Sie Folgendes:

var book = await context.Books.Include(b => b.Theme).First();
var theme = book.Theme;


Related

Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow