bedingt in linq zu Entitäten einschließen?

conditional entity-framework include linq

Frage

Ich hatte das Gefühl, dass das Folgende möglich sein sollte. Ich bin nur nicht sicher, wie ich vorgehen soll.

Ich würde gerne die include-Methode verwenden, um meine Ergebnisse zu formen, dh zu definieren, wie weit der Objektgraph durchlaufen werden soll. aber ... Ich möchte, dass diese Durchquerung bedingt ist.

something like...

dealerships
    .include( d => d.parts.where(p => p.price < 100.00))
    .include( d => d.parts.suppliers.where(s => s.country == "brazil"));

Ich verstehe, dass dies keine gültige linq ist, tatsächlich ist es schrecklich falsch, aber im Wesentlichen suche ich nach einem Weg, um einen Ausdrucksbaum zu erstellen, der geformte Ergebnisse liefert, die ...

select *
from dealerships as d
outer join parts as p on d.dealerid = p.dealerid
    and p.price < 100.00
outer join suppliers as s on p.partid = s.partid
    and s.country = 'brazil'

mit einem Schwerpunkt auf den Join-Bedingungen.

Ich fühle, dass dies mit esql recht geradlinig wäre, aber ich würde es vorziehen , Ausdrucksbäume im Handumdrehen zu bauen.

Wie immer dankbar für Ratschläge und Anleitungen

Akzeptierte Antwort

Das sollte den Trick tun:

using (TestEntities db = new TestEntities())
{
    var query = from d in db.Dealership
                select new
                {
                    Dealer = d,
                    Parts = d.Part.Where
                    (
                        p => p.Price < 100.0 
                             && p.Supplier.Country == "Brazil"
                    ),
                    Suppliers = d.Part.Select(p => p.Supplier)
                };

    var dealers = query.ToArray().Select(o => o.Dealer);
    foreach (var dealer in dealers)
    {
        Console.WriteLine(dealer.Name);
        foreach (var part in dealer.Part)
        {
            Console.WriteLine("  " + part.PartId + ", " + part.Price);
            Console.WriteLine
                (
                "  " 
                + part.Supplier.Name 
                + ", " 
                + part.Supplier.Country
                );
        }
    }
}

Dieser Code gibt Ihnen eine Liste von Händlern, die jeweils eine gefilterte Liste von Teilen enthalten. Jeder Teil verweist auf einen Lieferanten. Der interessante Teil ist, dass Sie die anonymen Typen in der ausgewählten Weise auf die gezeigte Weise erstellen müssen. Andernfalls ist das Teil-Eigentum der Dealership-Objekte leer.

Sie müssen auch die SQL-Anweisung ausführen, bevor Sie die Händler aus der Abfrage auswählen. Andernfalls ist das Part-Eigentum der Händler wieder leer. Deshalb habe ich den ToArray () - Aufruf in die folgende Zeile gestellt:

var dealers = query.ToArray().Select(o => o.Dealer);

Ich stimme mit Darren überein, dass dies möglicherweise nicht das ist, was die Benutzer Ihrer Bibliothek erwarten.


Beliebte Antwort

Bist du sicher, dass du das willst? Der einzige Grund, den ich frage, ist, dass, wenn Sie den Filter für Parts of Dealerships hinzugefügt haben, Ihre Ergebnisse nicht mehr als Dealerships gelten. Sie haben mit speziellen Objekten zu tun, die zum größten Teil Händlern nahe stehen (mit den gleichen Eigenschaften), aber die Bedeutung der Eigenschaft "Teile" ist unterschiedlich. Anstatt eine Beziehung zwischen Händler und Ersatzteilen zu sein, ist es eine gefilterte Beziehung.

Oder anders ausgedrückt, wenn ich einen Händler aus Ihren Ergebnissen ziehe und zu einer Methode übergebe, die ich geschrieben habe, und dann in meiner Methode ich anrufe:

var count = dealership.Parts.Count();

Ich erwarte, die Teile zu bekommen, nicht die gefilterten Teile aus Brasilien, wo der Preis unter 100 Dollar liegt.

Wenn Sie das Händlerobjekt nicht zum Übergeben der gefilterten Daten verwenden, ist dies sehr einfach. Es wird so einfach wie:

    var query = from d in dealerships
               select new { DealershipName = d.Name, 
CheapBrazilProducts = dealership.Parts.Where(d => d.parts.Any(p => p.price < 100.00) || d.parts.suppliers.Any(s => s.country == "brazil")) };

Wenn ich die gefilterten Sets nur wie gewünscht abrufen müsste, würde ich wahrscheinlich die oben erwähnte Technik verwenden und dann ein Werkzeug wie Automapper verwenden, um die gefilterten Ergebnisse aus meiner anonymen Klasse in die echte Klasse zu kopieren. Es ist nicht unglaublich elegant, aber es sollte funktionieren.

Ich hoffe das hilft! Es war ein interessantes Problem.



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum