Im Moment bin ich etwas mit dem EF zu Gange, allerdings tue ich mir etwas schwer (ist das erste Mal
). Eine “Eigenart” von EF ist, dass alle Referenzen explizit geladen werden müssen.
Ein Beispiel: Ein Customer hat mehrere Orders, genau eine CustomerAddress und jede Order hat eine DeliveryAddress.
Das hier geht ohne Probleme:
var customers = from customer in entities.Customers
select customer;
foreach (Customer customer in customers) {
Console.WriteLine(customer.CustomerNumber);
}
Das hier wirft allerdings eine NullReferenceException (bei :N Relationen würde hier eine leere, typisierte EntityCollection stehen):
var customers = from customer in entities.Customers
select customer;
foreach (Customer customer in customers) {
Console.WriteLine(customer.CustomerAddress.Street);
}
Um die Exception (bzw. die leere Collection) zu vermeiden, muss die Suche auf die Customer Objekte so aussehen:
var customers = from customer in entities.Customers.Include("CustomerAddress")
select customer; Dadurch wird das CustomerAddress-Objekt automatisch mit geladen. So weit so gut ..
Was passiert jetzt, wenn wir für alle Orders eines Customers z.B. die Straße der DeliveryAddress ausgeben wollen?
foreach (Customer customer in customers) {
foreach (Order order in customer.Orders) {
Console.WriteLine(order.DeliveryAddress.Street);
}
} Es passiert … gar nichts. Die Orders sind nämlich gar nicht geladen, deswegen wird die Schleife auch gar nicht betreten. Abhilfe schafft da die Load Methode der Orders Eigenschaft. Einmal Aufrufen und die Orders sind von der DB nachgeladen. Alternativ lässt sich auch der Include erweitern:
var customers = from customer in entities.Customers.Include("CustomerAddress").Include("Orders")
select customer; ACHTUNG: Diese Methode funktioniert nur für Properties am “Haupt”objekt der jeweiligen Abfrage (hier Customer).
Dann sind wir im oberen Beispiel allerdings wieder bei der NullReferenceException. Bei :1 Relationen ist das Spiel etwas anders: Hier wird eine zusätzliche <Eigenschaft>Reference Eigenschaft in der entsprechenden Entity generiert (im vorliegenden Beispiel hat ein Objekt der Klasse Order neben der DeliveryAddress Eigenschaft auch noch eine DeliveryAddressReference Eigenschaft), bei der ihr dann wiederum die Load Methode nutzen könnt, um die Referenz auch tatsächlich zu laden.
Insgesamt für mich etwas unintuitiv (doofes Wort
), aber wenn man weiß, worauf man achten muss, geht es. Auf jeden Fall vermeidet das EF dadurch erst mal unnötige DB-Abfragen.



