2010-01-29 7 views
5

J'ai une classe comme suit:Je ne comprends pas comment utiliser LINQ

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

Je puis créer une liste et le remplir avec des scans contenant tout.

Dim Scans As New List(Of Scan) 

J'ai besoin d'exploiter la liste pour obtenir diverses informations. Je voudrais utiliser LINQ pour le faire. Le problème est que pour la vie de moi, je ne comprends pas. La syntaxe me rejette, le fait que les résultats ne soient pas fortement typés me rejette, et l'échantillon sur le web est trop simplifié, ou trop compliqué.

Comment pourrais-je

  1. Obtenez un nombre de scans, regroupés par date où Livré = True
  2. Obtenir un nombre de scans, regroupés par facilité où Livré = True
  3. Obtenir un compte de scans , groupé par état où Delivered = True

Je veux ensuite utiliser ceci dans une boucle For Each.

For Each result In GroupedResults 
    ‘My Code 

Next 

Idéalement, j'aimerais que le résultat soit fortement typé. Est-ce possible?

Quelqu'un peut-il recommander des liens pour commencer? Chaque site Web que je rencontre me fait nager. Je ne comprends pas du tout.

EDIT:

Merci beaucoup les gars. Je suis toujours en train de me gratter la tête, mais au moins c'est un exemple concret que je peux utiliser pour avoir une idée de ce qui se passe.

J'espérais que cet exemple simple m'aiderait à utiliser une approche plus complexe - pas de chance pour le moment. J'aurais dû le demander d'emblée.

Tous les exemples semblent utiliser une réponse clé/valeur. Et si j'ai deux valeurs à regrouper?

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 

Est-il possible d'obtenir ceci dans un résultat?

Modifier Edit:

répondu à ma propre Modifier! Cela semble fonctionner pour moi:

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)} 

Merci beaucoup les gars. Vous m'avez au point où je pourrais pirater une solution. Je ne comprends toujours pas ce que je fais (Qu'est-ce que Function (s) ?!), mais j'ai quelque chose à commencer. J'ai l'intention de passer du temps à apprendre cela maintenant. Je pense que ce qui m'a vraiment découragé, c'est que les échantillons sur le net sont en C#. Normalement, je n'ai aucun problème à convertir la syntaxe, mais avec LINQ, ce n'est pas aussi simple. Je pensais que je faisais quelque chose de mal, mais c'était juste que la syntaxe était très différente.

+0

Voulez-vous des décomptes séparés pour chaque date de livraison? Donc, vos résultats seraient: 3 ont été livrés le jour X, 6 ont été livrés le jour Y ... etc Est-ce ce que vous cherchez? –

+1

Qu'est-ce qui vous fait penser que les résultats ne sont pas fortement typés? –

+0

Ils sont fortement typés. Si vous lancez simplement une requête vanilla (à partir de s comme Scan select s), il ne sera pas converti en scan, mais vous pouvez utiliser rapidement CType pour le faire. –

Répondre

4

Vous n'êtes pas limité à l'utilisation de la syntaxe de requête LINQ. Vous pouvez également utiliser les méthodes d'extension LINQ sur les collections.Le résultat que vous recevrez sera fortement typé. Bien que les types anonymes seront utilisés lorsque vous ne renvoyez pas un type existant.

Le code ci-dessous est C#, mais vous comprendrez:

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(); 

} 

Le résultat ici est pas vraiment typé, car une expression GroupBy retourne un type de IGrouping. Cependant, vous pouvez contourner ce problème, en faisant ceci:

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

En utilisant les méthodes d'extension LINQ fournit, peut-être vous aider à comprendre un peu plus.

Désolé pour la syntaxe C#, mais je ne suis pas vraiment familier avec VB.NET.

+0

généralement, la syntaxe de la requête est moins effrayante au début, pour ceux qui connaissent SQL et ne connaissent pas vraiment la syntaxe lambda, ce qui est assez horrible dans vb. –

+0

Sérieux. Cela s'est traduit par: Dim result2 = scans.Where (Fonction (s) s.Delivered). _ GroupBy (Fonction (s) s.Facilité). _ Sélectionnez (Fonction (s) Nouveau (s) avec {.Facility = s.Key, .NumberOfItems = s.Count()}) Ugly. – Brett

+0

Bien que ce ne soit pas la solution que j'ai finalement, c'est la réponse qui m'a mis sur la bonne voie. Merci! – Brett

0

Si vous souhaitez utiliser LINQ Je vous suggère de lire cette page sur l'utilisation de LINQ avec des objets (tels que votre propre classe Scan):

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

Il devrait être assez facile à comprendre sans causer votre tête pour tourner. :)

Sinon, je suggère d'utiliser la classe List elle-même qui a de nombreuses fonctions utiles. Consultez ici les informations à ce sujet:

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() }; 

excuses si le C# à la conversion vb est faux!

1

Je suis tombé sur la même confusion. Je suis d'accord que la documentation n'est pas très claire. J'utilise maintenant LINQ dans trois projets, et j'aime bien ça. Si vous utilisez LINQ to SQL, créez votre classe LINQ en créant une connexion à votre serveur dans Server View et en faisant glisser votre table dans votre contexte de données. Sinon, définissez db comme la collection de vos objets Scan.

1) Obtenir un nombre de scans, regroupés par date où Livrés = True

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

2) Obtenir un nombre de scans, regroupés par établissement où Livré = True

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

3) Obtenir le nombre de balayages, groupés par état où Delivered = True

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

Ce dernier recevra tous les résultats. sult rangées.Si vous voulez juste le compte comme numéro:

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

Si vous voulez toutes les dates de livraison séparés, vous pouvez faire la requête suivante:

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

Pour définir comme une source de données, il suffit de faire la suivant:

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

gridview1.DataSource = Query

Espérons que cela aide!

+0

Comment obtenez-vous le compte ici? Et, LINQ n'est pas forcément lié à une base de données. –

+0

Ceci est LINQ to SQL. Si vous souhaitez utiliser LINQ to Objects, vous n'utilisez pas de datacontext, mais utilisez la collection à la place de DataContext. –

Questions connexes