2010-08-29 4 views
8

Ich habe eine Lösung, wo ich Self-Tracking-Entitäten mit den RTM-Vorlagen erstellt haben. Ich habe die Entitäten und den Kontext zwischen zwei Projekten aufgeteilt, damit ich die Typdefinitionen wiederverwenden kann, wenn ich Client/Server über WCF ausführen möchte.Entity Framework 4: Eager Laden (Include) mit Filtern mit Self-Tracking-Entities

Eine meiner Servicemethoden ist erforderlich, um ein Diagramm von "Product" -Objekten mit untergeordneten Objekten von "ProductSku" zurückzugeben, und diese wiederum haben untergeordnete Objekte von "ProductPrice". Die Auswahlkriterien lauten auf die Eigenschaft "Name" des Objekts "Produkt" und die Eigenschaft "FinancialPeriodID" des "ProductPriceObject". Momentan schließe ich den Namen nicht in die Suche ein, aber ich habe Probleme, den Graphen zurückzubringen.

Wenn ich einfach die folgende Abfrage ausführen (beachten Sie, wird diese Syntax von LinqPad eher als der tatsächlichen Anwendungscode genommen) ...

from product in Products.Include("Skus.PriceHistory") 
select product 

... dann bin ich in der Lage, die volle Objektgraph abrufen Für die Artikel, die ich benötige, gibt es an dieser Stelle natürlich keinen Filter.

Wenn stattdessen stelle ich den Filter wie folgt ...

from product in Products.Include("Skus.PriceHistory") 
join sku in ProductSkus on product.ID equals sku.ProductID 
join price in ProductPrices on sku.ID equals price.ProductSkuID 
where price.FinancialPeriodID == 244 
select product 

... was ich erwarte zurück zu erhalten, ist das „Produkt“ Objekte, das Kind „productSku“ Objekte (die in sind die "Skus" -Kollektion des "Produkts") und ihre "ProductPrice" -Objekte (die in der "PriceHistory" -Sammlung des "ProductSku" enthalten sind) - aber ich bekomme nur die "Product" -Objekte zurück, die "Skus" -Kollektion leer.

ich auch als Codierung die Abfrage versucht haben ...

from product in Products.Include("Skus.PriceHistory") 
from sku in product.Skus 
from price in sku.PriceHistory 
where price.FinancialPeriodID == 244 
select product 

... aber das macht keinen Unterschied, entweder.

Offensichtlich muss ich etwas falsch machen. Kann irgendjemand etwas Licht auf das, was das ist, werfen, so wie ich es schon seit Stunden getan habe und jetzt im Kreis herumlaufe?

Antwort

1

Edit:

Was:

from product in Products.Include("Skus.PriceHistory") 
where product.Skus.Any(s => s.PriceHistory.Any(p => p.FinancialPeriodID == 244)) 
select product 

Include bereits alle erforderlichen Aufgaben ausführt Eigenschaften Navigation zu füllen, so zusätzliche Verknüpfungen für wo Zustand nicht benötigt werden. Was noch wichtiger ist, jede manuelle Verknüpfung oder Projektion ändert die Form der Abfrage und Include wird nicht verwendet.

Achten Sie auch, dass, wo Bedingung nur Produkte filtert. Die von Include geladenen Daten werden nicht gefiltert. Sie erhalten alle Produkte mit mindestens einem SKU mit einer Preishistorie mit der ID 244 für die finanzielle Periode, aber bei diesen Produkten werden alle Skus- und Preishistorien geladen. EF unterstützt derzeit nicht das Filtern nach Include. Wenn Sie auch gefilterte Beziehungen benötigen, müssen Sie separate Abfragen ausführen, um sie zu erhalten.

+0

Sorry „SKUs“ und „Preisentwicklung“ beiden Sammlungen, so ist es nicht möglich, Navigieren Sie in einer einzigen Anweisung den gesamten Pfad entlang. Ich fürchte, es gibt keine andere Möglichkeit, als die Joins entweder mit Join oder mit From aufzunehmen, wie in den beiden Beispielen gezeigt. Danke trotzdem. –

+0

Das hat @MartinRobins vielleicht nicht geholfen, aber es hat mir bei meinem eigenen Projekt geholfen! +1 Diese Syntax funktionierte für mich (vielleicht völlig anders Setup als ursprüngliche Frage, ich weiß nicht ...) – BenSwayne

1

Vielleicht kann Projektion diesen Trick machen?

Werfen Sie einen Blick auf Linq filter collection with EF

+0

Danke, aber ich möchte wirklich die Anzahl der Objekttypen minimieren, die ich herumgereicht bin. Ich habe bereits einen vollkommen guten "Produkt" -Typ, ich möchte nur, dass das eifrige Laden ordnungsgemäß funktioniert, damit die untergeordneten Objekte gefüllt werden. –

-1

Selbst Tracking-Einheiten sind verzögertes Laden ausführen nicht aktiviert. Deshalb ist die Sammlung nicht leer mit der Standard-Entity-Generierung und nicht mit STE. Tatsächlich lädt Ihr Include niemals verbundene Entitäten, wenn Sie sie in der Abfrage verwenden. Jetzt ist Ihre L2E-Abfrage nicht korrekt.Ich denke, dass Sie so etwas wie dies tun wollen:

Hoffnung, die

Matthieu

+0

Ich versuche nicht, lazy loading zu verwenden; Ich versuche eifrig zu laden. Wenn ich die Where-Klausel entferne oder sie nur auf dem Top-Level-Objekt basiere, bekomme ich alle Objekte richtig. Nur wenn ich die where-Klausel auf der Grundlage von Eigenschaften der untergeordneten Objekte verwende, wird das "Include" ignoriert. –

+0

Hallo Martin, hast du eine Lösung gefunden, habe ich das selbe Problem – freddoo

0

schließen hilft, ist keine Garantie eifrig Laden zu haben und es leise aus folgendem Grund ignoriert werden konnte Grund. Es ist besser in diesem Thread erklärt. Sie können manuell die Tabelle auswählen, die Sie laden möchten, z.

var result = from product in Products.Include("Skus.PriceHistory") 
from sku in product.Skus 
from price in sku.PriceHistory 
where price.FinancialPeriodID == 244 
select new { p=product, pricehistory = product.Skus.PriceHistory}; 
var products = results.select(pph => pph.product); 

https://social.msdn.microsoft.com/Forums/en-US/76bf1f22-7674-4e1e-85d3-68d29404e8db/include-is-ignored-in-a-subquery?forum=adodotnetentityframework

  • nur einschließen, um Elemente in den Abfrageergebnissen gilt: Objekte, die am äußersten Betrieb in der Abfrage projiziert sind.
  • Der Typ der Ergebnisse muss ein Entitätstyp sein.
  • Die Abfrage kann nicht enthalten Operationen, die den Typ des Ergebnis ändern zwischen einschließen und die äußerste Betrieb (dh ein GroupBy() oder ein Select() Operation, die den Ergebnistyp ändert)
  • Der Parameter durch Fügen genommen ist ein Punkt-getrennter Weg der Navigations Eigenschaften, die von einer Instanz des Typs, die an dem äußersten Betrieb navigierbar sein müssen, um zurück
Verwandte Themen