2010-01-29 8 views
5

ich eine Klasse wie folgt:Ich verstehe einfach nicht, wie Linq verwenden

Class Scan 
    Delivered As Boolean 
    ScanDate As Date 
    State As String 
    Facility As String 
End Class 

ich dann eine Liste erstellen und füllen es mit Scans, was auch immer enthält.

Ich muss die Liste abbauen, um verschiedene Informationen zu erhalten. Ich würde gerne LINQ verwenden, um es zu tun. Das Problem ist, dass ich es für mein Leben nicht verstehe. Die Syntax wirft mich ab, die Tatsache, dass die Ergebnisse nicht stark typisiert sind, wirft mich ab, und die Beispiele im Web sind zu stark vereinfacht oder zu kompliziert.

Wie konnte ich

  1. eine Anzahl von Scans holen nach Datum gruppiert, wo wahre Delivered =
  2. eine Anzahl von Scans holen von der Einrichtung gruppiert, wo wahre Delivered =
  3. eine Anzahl von Scans Get , gruppiert nach Staat, wo geliefert = wahr

Ich möchte dann dies in einer For Each-Schleife verwenden.

For Each result In GroupedResults 
    ‘My Code 

Next 

Idealerweise hätte ich gerne das Ergebnis stark typisiert. Ist das möglich?

Kann jemand einige Links empfehlen, um damit zu beginnen? Jede Website, die mir begegnet, bringt mich nur zum Schwimmen. Ich verstehe es überhaupt nicht.

EDIT:

Vielen Dank Jungs. Ich kratze mich immer noch mit dem Kopf über dieses Zeug, aber zumindest ist dies ein Beispiel aus der realen Welt, das ich verwenden kann, um eine Vorstellung davon zu bekommen, was vor sich geht.

Ich hatte gehofft, dass dieses einfache Beispiel mir helfen würde, in einen komplexeren Gebrauch zu springen - noch kein Glück. Ich hätte das auf Anhieb fragen sollen.

Alle Beispiele scheinen eine Schlüssel/Wert-Antwort zu verwenden. Was ist, wenn ich zwei Werte habe, die ich gruppieren muss?

Class Scan 
     Delivered As Boolean 
     Scanned As Boolean 
     ScanDate As Date 
     State As String 
     Facility As String 
    End Class 


1. Get a count of Delivered = True, a count of Scanned=True, grouped by Date 
2. Get a count of Delivered = True, a count of Scanned=True, grouped by Facility 
3. Get a count of Delivered = True, a count of Scanned=True, grouped by State 

Ist es möglich, dies in einem Ergebnis zu erhalten?

bearbeiten Edit:

Beantwortet meine eigene bearbeiten! Dies scheint für mich zu arbeiten:

Dim query = From r In scans _ 
      Group r By r.ScanDate Into g = Group _ 
      Select New With _ 
      {g, .DeliveredCount = g.Count(Function(s) s.Delivered), .ScannedCount = g.Count(Function(s) s.Scanned)} 

Vielen Dank Jungs. Sie haben mich zu dem Punkt gebracht, wo ich eine Lösung heraushacken könnte. Ich verstehe immer noch nicht, was ich tue (Was ist Funktion (en) ?!), aber ich habe etwas, womit ich anfangen kann. Ich habe vor, Zeit damit zu verbringen, das jetzt zu lernen. Ich denke, was mich wirklich abschreckte ist, dass die Samples im Netz C# sind. Normalerweise habe ich kein Problem, die Syntax zu konvertieren, aber mit LINQ ist das nicht so einfach. Ich dachte, ich würde etwas falsch machen, aber es war nur, dass die Syntax sehr unterschiedlich war.

+0

Wünschen Sie separate Zählungen für jeden Liefertermin? Ihre Ergebnisse wären also: 3 wurden am Tag X geliefert, 6 wurden am Tag Y geliefert ... etc. Ist das, wonach Sie suchen? –

+1

Was lässt Sie glauben, dass die Ergebnisse nicht stark typisiert sind? –

+0

Sie sind stark typisiert. Wenn Sie nur eine Vanilla-Abfrage (von s als Scan select s) ausführen, wird es nicht als Scan umgewandelt, aber Sie können einfach CType dazu verwenden. –

Antwort

4

Sie können die LINQ-Abfragesyntax nicht verwenden. Sie können auch die LINQ-Erweiterungsmethoden für die Sammlungen verwenden.

Das Ergebnis, das Sie erhalten, wird stark typisiert. Anonyme Typen werden zwar verwendet, wenn Sie keinen vorhandenen Typ zurückgeben.

Der folgende Code ist C#, aber Sie werden verstehen:

static void Main(string[] args) 
{ 
    List<Scan> scans = new List<Scan>(); 

    scans.Add (new Scan (new DateTime (2010, 1, 1), true, "Facility1")); 
    scans.Add (new Scan (new DateTime (2010, 1, 1), true, "Facility2")); 
    scans.Add (new Scan (new DateTime (2010, 1, 1), false, "Facility3")); 
    scans.Add (new Scan (new DateTime (2010, 1, 26), true, "Facility1")); 

    var result1 = scans.Where (s => s.Delivered).GroupBy (s => s.ScanDate); 

    foreach(var r in result1) 
    { 
     Console.WriteLine (String.Format ("Number of delivered scans for {0}: {1}", r.Key, r.Count())); 
    } 

    var result2 = scans.Where (s => s.Delivered).GroupBy (s => s.Facility); 

    foreach(var r in result2) 
    { 
     Console.WriteLine (String.Format ("Number of delivered scans for {0}: {1}", r.Key, r.Count())); 
    } 

    Console.ReadLine(); 

} 

Das Ergebnis hier nicht wirklich geschrieben wird, da ein GroupBy Ausdruck einen IGrouping Typ zurückgibt. Allerdings können Sie dieses Problem umgehen, indem Sie dies tun:

var result2 = scans.Where (s => s.Delivered) 
        .GroupBy (s => s.Facility) 
        .Select(s => new { Facility = s.Key, NumberOfItems = s.Count() }); 

Mit den Erweiterungsmethoden, die LINQ bietet, vielleicht kann Ihnen helfen, es ein bisschen mehr verstehen.

Sorry für die C# -Syntax, aber ich bin nicht wirklich mit VB.NET vertraut.

+0

Im Allgemeinen ist die Abfragesyntax anfangs weniger beängstigend für diejenigen, die SQL kennen und nicht wirklich die Lambda-Syntax kennen, was in vb ziemlich grässlich ist. –

+0

Ernsthaft. Dies wurde übersetzt in: Dim result2 = Scans.Where (Funktion (en) s.Lieferung). _ GroupBy (Funktion (en) s.Facility). _ Auswählen (Funktion (en) Neu mit {.Facility = s.Key, .NumberOfItems = s.Count()}) Hässlich. – Brett

+0

Obwohl dies nicht die Lösung ist, die ich letztendlich habe, ist es die Antwort, die mich auf den richtigen Weg gebracht hat. Vielen Dank! – Brett

0

Wenn Sie LINQ verwenden möchten würde ich mit Objekten zur Verwendung von LINQ Lesen dieser Seite vorschlagen (wie Ihre eigene Klasse Scan):

http://msdn.microsoft.com/en-us/library/bb397937.aspx

Es sollte einfach genug sein, ohne zu verstehen, was Ihre Kopf um zu drehen. :)

Ansonsten würde ich vorschlagen, die List-Klasse selbst zu verwenden, die viele hilfreiche Funktionen hat. Schauen Sie hier für Informationen über das:

http://msdn.microsoft.com/en-us/library/d9hw1as6.aspx

2
Dim GroupedResults = from s in Scans _ 
        where Delivered _ 
        group s by ScanDate into g //edit here for the others _ 
        select new { Category = g.Key, ScanCount = g.Count() }; 

Entschuldigungen, wenn die C# vb Umwandlung falsch ist!

1

Ich stieß auf die gleiche Verwirrung. Ich stimme zu, dass die Dokumentation nicht sehr klar ist. Ich benutze jetzt LINQ in drei Projekten, und ich mag es.

Wenn Sie LINQ to SQL verwenden, erstellen Sie Ihre LINQ-Klasse, indem Sie eine Verbindung zu Ihrem Server in der Serveransicht erstellen und die Tabelle in den Datenkontext ziehen. Andernfalls setzen Sie db als Sammlung Ihrer Scan-Objekte.

1) Erhalten Sie eine Anzahl von Scans nach Datum gruppiert, wo wahre Delivered =

Dim db = new BrettsDataContext 
Dim Query = From s as Scan in db _ 
Where s.Delivered = True _ 
Order By s.Date

2) Erhalten Sie eine Anzahl von Scans, die von der Einrichtung gruppiert, wo wahre Delivered =

Dim db = new BrettsDataContext 
Dim Query2 = From s as Scan in db _ 
Where s.Delivered = True _ 
Order By s.Date

3) Anzahl der Scans, gruppiert nach Status, wo Geliefert = Wahr

Dim db = new BrettsDataContext 
Dim Query3 = From s as Scan in db _ 
Where s.Delivered = True _ 
Order By s.State

Das letzte wird alle re erhalten Sult Reihen.Wenn Sie nur die Anzahl als Zahl wollen:

Dim count = (From s as Scan in db _ 
Where s.Delivered = True).Count

Wenn Sie alle separaten Lieferdaten wollten, können Sie die folgende Abfrage tun könnte:

Dim db = new BrettsDataContext 
Dim Query4 = From s as Scan in db _ 
Where s.Delivered = True _ 
Order By DeliveryDate

Um als Datenquelle einzustellen, führen Sie nur die folgende:

Dim db = new BrettsDataContext 
Dim Query = From s as Scan in db _ 
Where s.Delivered = True _ 
Order By s.Date 

gridview1.DataSource = Query

Hoffe, das hilft!

+0

Wie bekommen Sie den Graf hier? Und LINQ ist nicht unbedingt mit einer DB verbunden. –

+0

Dies ist LINQ to SQL. Wenn Sie LINQ to Objects verwenden möchten, verwenden Sie keinen Datenkontext, sondern verwenden die Auflistung anstelle von DataContext. –