Nach dem, was ich aus der Dokumentation von SelectMany verstehe, könnte man damit eine (abgeflachte) Sequenz einer 1-viele-Beziehung erzeugen.
Ich habe folgende Klassen
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
class Order
{
public int Id { get; set; }
public int CustomerId { get; set; }
public string Description { get; set; }
}
Ich versuche dann, sie unter Verwendung der Abfrageausdruckssyntax wie folgt zu verwenden
var customers = new Customer[]
{
new Customer() { Id=1, Name ="A"},
new Customer() { Id=2, Name ="B"},
new Customer() { Id=3, Name ="C"}
};
var orders = new Order[]
{
new Order { Id=1, CustomerId=1, Description="Order 1"},
new Order { Id=2, CustomerId=1, Description="Order 2"},
new Order { Id=3, CustomerId=1, Description="Order 3"},
new Order { Id=4, CustomerId=1, Description="Order 4"},
new Order { Id=5, CustomerId=2, Description="Order 5"},
new Order { Id=6, CustomerId=2, Description="Order 6"},
new Order { Id=7, CustomerId=3, Description="Order 7"},
new Order { Id=8, CustomerId=3, Description="Order 8"},
new Order { Id=9, CustomerId=3, Description="Order 9"}
};
var customerOrders = from c in customers
from o in orders
where o.CustomerId == c.Id
select new
{
CustomerId = c.Id
, OrderDescription = o.Description
};
foreach (var item in customerOrders)
Console.WriteLine(item.CustomerId + ": " + item.OrderDescription);
Das gibt was ich brauche.
1: Order 1
1: Order 2
1: Order 3
1: Order 4
2: Order 5
2: Order 6
3: Order 7
3: Order 8
3: Order 9
Ich gehe davon aus, dass dies zur Verwendung der SelectMany-Methode führt, wenn die Syntax des Abfrageausdrucks nicht verwendet wird.
In beiden Fällen versuche ich, meinen Kopf mit SelectMany herumzuwickeln. Könnte mir jemand eine Linq-Abfrage mit SelectMany zur Verfügung stellen, selbst wenn meine obige Abfrage angesichts der beiden Klassen und Scheindaten nicht in SelectMany übersetzt wird?
c#
linq
data-structures
linq-to-objects
Jackie Kirby
quelle
quelle
Antworten:
Hier ist Ihre Abfrage mit
SelectMany
, genau nach Ihrem Beispiel modelliert. Gleiche Ausgabe!Das erste Argument ordnet jeden Kunden einer Sammlung von Bestellungen zu (völlig analog zu der bereits vorhandenen 'where'-Klausel).
Das zweite Argument wandelt jedes übereinstimmende Paar {(c1, o1), (c1, o2) .. (c3, o9)} in einen neuen Typ um, den ich wie in Ihrem Beispiel erstellt habe.
So:
Die resultierende Sammlung ist flach, wie Sie es in Ihrem ursprünglichen Beispiel erwarten würden.
Wenn Sie das zweite Argument weglassen würden, würden Sie am Ende eine Sammlung aller Bestellungen erhalten, die einem Kunden entsprechen. Es wäre genau das, eine flache Sammlung von
Order
Objekten.Die Verwendung ist sehr gewöhnungsbedürftig, manchmal habe ich immer noch Probleme, meinen Kopf darum zu wickeln. :(
quelle
GroupBy
könnte eine bessere Option für dieses spezielle Szenario sein.SelectMany () funktioniert wie Select, jedoch mit der zusätzlichen Funktion, eine ausgewählte Sammlung zu reduzieren. Es sollte immer dann verwendet werden, wenn Sie eine Projektion von Elementen von Untersammlungen wünschen, und sich nicht um das enthaltende Element der Untersammlung kümmern.
Angenommen, Ihre Domain sah folgendermaßen aus:
Um die gleiche Liste zu erhalten, die Sie wollten, würde Ihr Linq ungefähr so aussehen:
... die das gleiche Ergebnis erzielen, ohne dass die flache Sammlung von Bestellungen erforderlich ist. Das SelectMany nimmt die Auftragssammlung jedes Kunden und durchläuft diese, um eine
IEnumerable<Order>
aus einer zu erstellenIEnumerable<Customer>
.quelle
Obwohl dies eine alte Frage ist, dachte ich, ich würde die hervorragenden Antworten ein wenig verbessern:
SelectMany gibt für jedes Element der Controlling-Liste eine Liste zurück (die möglicherweise leer ist). Jedes Element in diesen Ergebnislisten wird in der Ausgabesequenz der Ausdrücke aufgelistet und somit mit dem Ergebnis verknüpft. Daher eine 'Liste -> b' Liste [] -> verketten -> b 'Liste.
quelle
Hier ist eine weitere Option mit SelectMany
Wenn Sie das Entity Framework oder LINQ to Sql verwenden und eine Zuordnung (Beziehung) zwischen den Entitäten haben, können Sie dies tun:
quelle