2010-01-29 14 views
5

tengo una clase de la siguiente manera:Simplemente no entender cómo usar LINQ

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

continuación, se crea una lista y rellenarlo con las exploraciones que contiene lo que sea.

Dim Scans As New List(Of Scan) 

Necesito extraer la lista para obtener varias informaciones. Me gustaría usar LINQ para hacerlo. El problema es que, por mi vida, simplemente no lo entiendo. La sintaxis me decepciona, el hecho de que los resultados no estén fuertemente tipados me saca de quicio, y la muestra en la web se simplifica demasiado o se complica demasiado.

¿Cómo podría

  1. Obtener un recuento de las exploraciones, agrupados por fecha donde Entregado = True
  2. obtener el número de exploraciones, agrupados por instalación donde Entregado = True
  3. obtener el número de exploraciones , agrupados por estado donde se entrega = verdadero

Luego quiero usar esto en un bucle For Each.

For Each result In GroupedResults 
    ‘My Code 

Next 

Idealmente, me gustaría que el resultado sea muy tipado. es posible?

¿Alguien puede recomendar algunos enlaces para comenzar con esto? Cada sitio web con el que me encuentro me hace nadar. No lo estoy entendiendo en absoluto.

EDIT:

Muchas gracias chicos. Todavía estoy rascándome la cabeza con estas cosas, pero al menos este es un ejemplo del mundo real que puedo usar para tener una idea de lo que está sucediendo.

Tenía la esperanza de que este simple ejemplo me ayudara a utilizar el tablero en un uso más complejo, sin suerte todavía. Debería haber preguntado esto de la nada.

Todos los ejemplos parecen utilizar una respuesta de clave/valor. ¿Qué pasa si tengo dos valores que necesito agrupar?

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 

¿Es posible obtener esto en un resultado?

Editar Editar:

respondido a mi propia edición! Esto parece estar funcionando para mí:

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

Muchas gracias chicos. Me has llevado al punto donde podría hackear una solución. Todavía no "entiendo" lo que estoy haciendo (¿Qué es Function (s) ?!), pero tengo algo para empezar. Tengo la intención de pasar el tiempo aprendiendo esto ahora. Creo que lo que realmente me sorprendió es que las muestras en la red son C#. Normalmente no tengo problemas para convertir la sintaxis, pero con LINQ esto no es tan simple. Pensé que estaba haciendo algo mal, pero era solo que la sintaxis era muy diferente.

+0

¿Quiere contar por separado para cada fecha de entrega? Entonces, sus resultados serían: 3 fueron entregados el día X, 6 fueron entregados el día Y ... etc. ¿Es esto lo que está buscando? –

+1

¿Qué te hace pensar que los resultados no están fuertemente tipados? –

+0

Están fuertemente tipados. Si solo ejecuta una consulta simple (de s como Selección de escaneo), no se lanzará como un escaneo, pero puede usar rápidamente CType para hacerlo. –

Respuesta

4

No tiene limitaciones para utilizar la sintaxis de consulta de LINQ. También puede usar los métodos de extensión LINQ en las colecciones.

El resultado que recibirá será fuertemente tipado. Aunque se usarán tipos anónimos cuando no devuelva un tipo existente.

El código siguiente es C#, pero lo entenderás:

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

} 

El resultado aquí no es realmente mecanografiadas, ya que una expresión GroupBy devuelve un tipo IGrouping. Sin embargo, puede evitar esto, al hacer esto:

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

Utilizando los métodos de extensión que proporciona LINQ, tal vez puede ayudar a entender un poco más.

Disculpe la sintaxis de C#, pero no estoy muy familiarizado con VB.NET.

+0

en general, la sintaxis de la consulta es menos aterradora al principio, para aquellos que conocen SQL y realmente no conocen la sintaxis lambda, que es bastante espantosa en vb. –

+0

Serio. Esto se tradujo a: Dim resultado2 = escaneos. Donde (función (es) s.Delivered). _ GroupBy (Function (s) s.Facility). _ Seleccionar (Función (es) Nuevo con {.Facility = s.Key, .NumberOfItems = s.Count()}) Ugly. – Brett

+0

Aunque esta no es la solución que finalmente tengo, es la respuesta que me puso en el camino correcto. ¡Gracias! – Brett

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

disculpas si el C# para la conversión vb está mal!

1

Me encontré con la misma confusión. Estoy de acuerdo en que la documentación no es muy clara. Ahora uso LINQ en tres proyectos, y me gusta bastante.

Si está utilizando LINQ to SQL, cree su clase LINQ creando una conexión con su servidor en Server View y arrastrando su tabla a través de su Contexto de datos. De lo contrario, simplemente configure db como la colección de sus objetos de escaneo.

1) Obtener un recuento de las exploraciones, agrupados por fecha donde Entregado = True

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

2) Obtener un recuento de las exploraciones, agrupados por instalación donde Entregado = True

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

3) Obtener un recuento de las exploraciones, agrupados por Estado donde Entregado = True

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

Esto último obtendrá toda la re sult filas.Si lo que desea es el recuento como un número:

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

Si quieres todas las fechas de entrega por separado, se puede hacer la siguiente consulta:

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

establecer como una fuente de datos, acaba de hacer el siguiente:

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

gridview1.DataSource = Query

Espero que esto ayude!

+0

¿Cómo se obtiene el conteo aquí? Y, LINQ no está necesariamente relacionado con una base de datos. –

+0

Esto es LINQ to SQL. Si quisiera usar LINQ to Objects, no usaría un contexto de datos, pero use la colección en lugar de DataContext. –

Cuestiones relacionadas