Bei den ersten Gehversuchen mit dem ADO.Net Entity Framework bin ich direkt auf die Tatsache gestoßen, dass per default die Subentities nicht direkt geladen werden.
Wenn beispielsweise eine Datenbankentity Kunde vorhanden ist, die beliebig viele Bestellungen als Subentities haben kann, werden bei einem Standardladevorgang a la
var allCustomers = myEntityModels.Customers;
lediglich die Kunden aus der entsprechenden Tabelle in der Datenbank geladen. Die ebenfalls benötigten Bestellungen werden hierbei ignoriert.
Um dieses Problem zu umgehen, gibt es zwei Möglichkeiten.
1. Explizites laden von Sub-Entities
Bei der ersten Variante werden die Subentities durch den Aufruf der Methode Load() auf der entsprechenden Property der gewünschten Instanz(en) geladen. Wenn zum Beispiel alle Bestellungen des Kunden mit der Id 5 geladen werden sollen sieht das Ganze wie folgt aus:
var suggestedCustomer = allCustomers.FirstOrDefault(delegate(Customer any) { return any.Id == 5; });
if(suggestedCustomer !=null)
suggestedCustomer.Orders.Load();
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
Danach sind die Bestellungen des Kunden verfügbar und können wie gewohnt verwendet werden, hierbei ist allerdings zu beachten, dass ein zusätzlicher Roundtrip zur Datenbank gemacht wird und somit der Load des Application und des Datenbankservers hochgeht.
2. Der Include Operator
Falls in einem Anwendungsszenario direkt alle Bestellungen aller Kunden benötigt werden, kann man auf einen Include Operator zurückgreifen. Das EF lädt demnach direkt alle Kunden mit allen Bestellungen, dadurch kann ein weiterer RoundTrip vermieden werden. Ausgehend von dem bekannten Datenbankmodell sieht der Ausdruck wie folgt aus
var allMyStuff = myEntityModels.Customers.Include(“Orders”);
Der angegebene Parameter “Orders” entspricht dem Propertynamen aus dem Entitymodel.
Hierbei ist zu beachten dass die Ladezeit der Entities im ersten Moment natürlich länger dauert, diese Zeit kann allerdings im Programmfluss wieder eingespart werden.
Fazit
Hierbei muss ganz klar vom Entwickler entschieden werden wie die Entities geladen werden müssen, abhängig von der verwendeten Lademethode werden andere Dinge wichtig wie zum Beispiel die berühmten UI Freezes usw.. Bei komplexen Datenbankmodellen liegt der Vorteil ganz klar in der Lazy-Loading-Variante, dadurch kann man lange Ladezeiten beim Start vermeiden, wodurch die Anwendung für den Endanwender bereits auf den ersten Blick performant aussieht.
