2010-12-17 13 views
12

Estoy escribiendo una función que extrae registros de una base de datos usando LINQ para obtener un IQueryable. Esta declaración LINQ extraerá todos los registros para usuarios Activos dentro de un cierto período de tiempo, y luego escupirá el ID de Usuario, el Nombre y el Apellido a un Telerik RadGrid.Devolviendo una IQueryable Distintiva con LINQ?

Mi problema consiste en tratar de obtener un Valor Distinto en el ID de Usuario al extraer estos Datos. He intentado volver a trabajar este código para obtener mi resultado. Aquí está el ejemplo del código que está extrayendo todos los datos, con el Distintivo NO funcionando.

public static IQueryable GetActiveEmployees_Grid(string Period) 
{ 
    DataContext Data = new DataContext(); 
    var Employees = (from c in DataSystem_Records 
        where c.Period == Period 
        orderby c.DataSystem_Employees.LName 
        select c).Distinct(); 

    return Employees; 
} 

Después de aplicar la fuente de datos a la red, éste devuelve al usuario 4 veces, una instancia para cada registro para ese período.

alt text

¿Hay una manera de aplicar Distinto a mi función de LINQ para hacer este trabajo la forma en que la intención es que?

Respuesta

20

La forma más simple que he encontrado para hacer esto con el objeto es usar el grupo y luego seleccionar el primero.

public static IQueryable GetActiveEmployees_Grid(string Period) 
{ 
    DataContext Data = new DataContext(); 
    var Employees = (from c in DataSystem_Records 
        where c.Period == Period 
        orderby c.DataSystem_Employees.LName 
        select c).GroupBy(g=>g.DataSystem_Employees.AccID).Select(x=>x.FirstOrDefault()); 

    return Employees; 
} 

Esto no está probado pero el concepto general está ahí.

Editar: Recuerdo haber encontrado la respuesta originalmente en algún lugar aquí. Mira esto para agrupar objetos por una propiedad determinada. LINQ's Distinct() on a particular property

+1

¡El GroupBy funcionó perfecto!Inicialmente probé el GroupBy cuando solucioné problemas, pero me perdí el .Select (x => x.FirstOrDefault()). ¡Gracias! – Lando

+0

El orden por debe estar en la selección después del grupo antes del primero o predeterminado. asumiendo que te importa el tiempo de inicio de sesión. –

4

Si limita los objetos que está volviendo solo a los campos que desea mostrar, funcionará correctamente.

public static IQueryable GetActiveEmployees_Grid(string Period) 
{ 
    DataContext Data = new DataContext(); 
    var Employees = (from c in DataSystem_Records 
        where c.Period == Period 
        orderby c.DataSystem_Employees.LName 
        select c.DataSystem_Employees.FName, 
          c.DataSystem_Employees.LName, 
          c.ID).Distinct(); 

    return Employees; 
} 
+0

En teoría, esto debería haber funcionado, pero IntelliSense me negó cuando intenté agregar más de una entidad a la declaración. – Lando

+0

¿Qué error estás recibiendo? – sgriffinusa

+0

@sgriffinusa, debe 'seleccionar nuevo {}' ... ya que su sintaxis es inválida –

4

tratar de escribir un IEqualityComparer<T> para el tipo de objeto que se seleccionan y se usan en su Distinct método

+2

esto usará linq para objetos que no son una consulta compuesta –

2

hacer algunas suposiciones en torno a los nombres de los distintos campos en los objetos:

public static IQueryable GetActiveEmployees_Grid(string Period) 
{ 
    DataContext Data = new DataContext(); 
    var Employees = (from c in DataSystem_Records 
        where c.Period == Period 
        orderby c.DataSystem_Employees.LName 
        select new { FirstName = c.DataSystem_Employees.FName, LastName = c.DataSystem_Employees.LName, ID = c.DataSystem_Employees.ID }).Distinct(); 

    return Employees; 
} 

Para seguir el patrón de MVC, es posible que desee levantar esta consulta en su Modelo y devolver una clase específica que contenga esos campos.

-1

El problema es que está retirando los campos que harán que cada fila sea distinta. Como dijo sgriffinusa, solo retire los 3 valores que está mostrando.

-1

Es posible que desee implementar un comparador personalizado para el método Distinct. Consulte una pregunta SO anterior here.

0

Utilice el método Distinct() para hacer esto. Ej:

var query = from Notification in db.Notifications 

         select Notification.client ; 
      query=query.Distinct(); 

la consulta resultante sólo contendrá valores distintos.

Cuestiones relacionadas