2012-04-02 18 views
11

Tengo un PC Enity que tiene algunas Propiedades, me gustaría devolver una lista de Objeto distinto (PC o Tipo Complejo o lo que sea) basado en una propiedad para vincularlo a los controles del servidor como La lista desplegable . Y como mi método se encuentra en BLL, no puedo devolver el tipo anónimo, así que creé un Branch ComplexType que tiene dos peroperties.Entity Framework devolviendo expedientes distintos problema

me escribió como este, pero que tienen registros repeative:

List<Branch> result = (from p in _context.PCs 
         where p.UserId== userId 
         select new Branch() 
            { 
             BranchId= p.BranchId, 
             BranchName=p.BranchName 
            }).Distinct().ToList(); 

Editar: Gracias a todos, Esto funcionó:

List<PC> result = _context.PCs 
        .GroupBy(p=>p.BranchName , p.BranchId}) 
        .select(g=>g.First()) 
        .ToList(); 
+0

¿Quiere decir que usted tiene dos elementos en la lista 'result' cual son iguales tanto en 'BranchId' como' BranchName' Esto sería sorprendente porque eso no debería suceder con su ejemplo. – Slauma

+0

Sí Lo hace bien – Mostafa

+0

¿Utiliza SQL Server? Si es así, ¿qué versión? Si no, ¿qué base de datos? – Slauma

Respuesta

9

esto devolverá las filas distintas para todas las columnas de la declaración de selección. Si desea filas distintas para una columna en particular simplemente especificar que la columna en particular

List<Branch> result = (from p in _context.PCs 
         where p.UserId== userId 
         select new Branch() 
            { 
             BranchId= p.BranchId, 
            }).Distinct().ToList(); 

Si desea obtener valores distintos basados ​​en múltiples columnas, entonces usted tiene que crear un grupo y luego recoger primer valor de ese grupo. En ese caso no utilizará distinto, por ejemplo

List<Branch> distinctResult = _context.PCs 
    .GroupBy(p => new Branch {p.BranchId, p.BranchName}) 
    .Select(g => g.First()) 
    .ToList(); 
+0

Gracias. El primer código no funcionó, devuelve registros repetitivos y necesito branchName. – Mostafa

+0

@Mostafa, reemplace BranchId, con BranchName en el primer statemet – Habib

+0

El segundo tampoco funcionó. Obtiene el error de tiempo de compilación: No se puede convertir el tipo de fuente System.Collection.Generic.List <...Pc> al tipo de destino System.Collection.Generic.List <...Branch> – Mostafa

2

Se obtiene duplicados porque Distinct() es incapaz de reconocer a dos de sus objetos complejos como Branch idéntica de sus propiedades. Simplemente comparará para la igualdad de objetos, que devolverá falso (porque crea dos objetos diferentes, pero con los mismos valores).

Puede usar Distinct(IQueryable, IEqualityComparer) para proporcionar su propio Comparer o implementar la interfaz IEquatable.

+0

El ejemplo en la pregunta es LINQ to Entities ('Distinct' of' IQueryable '), no LINQ to Objects (' Distinct' of 'IEnumerable '). La comparación de igualdad de objeto no se aplica en este caso. – Slauma

+0

Tienes razón, bien llamado. Wrong Distinct() aquí. Pero, ¿todavía no solucionaría [proporcionando un IEqualityComparer] (http://msdn.microsoft.com/en-us/library/bb356803.aspx)? – magnattic

+0

No, porque la sobrecarga de 'Distinct' que toma el' IEqualityComparer' no se admite en LINQ to Entities. De hecho, estoy muy confundido sobre por qué el ejemplo en la pregunta no funciona. Voy a probarlo ... – Slauma

2

No puedo reproducir el problema (probado con SQL Server 2008 R2 y EF 4.1/DbContext). La consulta en su pregunta ...

List<Branch> result = (from p in _context.PCs 
         where p.UserId== userId 
         select new Branch() 
         { 
          BranchId = p.BranchId, 
          BranchName = p.BranchName 
         }) 
         .Distinct() 
         .ToList(); 

... genera el siguiente código SQL:

SELECT 
[Distinct1].[C1] AS [C1], 
[Distinct1].[BranchId] AS [BranchId], 
[Distinct1].[BranchName] AS [BranchName] 
FROM (SELECT DISTINCT 
     [Extent1].[BranchId] AS [BranchId], 
     [Extent1].[BranchName] AS [BranchName], 
     1 AS [C1] 
     FROM [dbo].[PCs] AS [Extent1] 
) AS [Distinct1] 

Es un DISTINCT en ambas columnas y me da el resultado esperado distinta - no hay duplicados en BranchId y BranchName.

+0

Gracias por su esfuerzo, tal vez sea porque la clave de la entidad de PC que es PCId y no BranchId – Mostafa

1

Esto funciona para mí.

1.

class RolBaseComparer:IEqualityComparer<RolBase> 
{ 
    public RolBaseComparer() 
    { 

    } 

    public bool Equals(RolBase x, RolBase y) 
    { 
     if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) 
     { 
      return false; 
     } 

     if (Object.ReferenceEquals(x, y)) 
     { 
      return true; 
     } 

     return x.Id.Equals(y.Id) && 
       x.Nombre.Equals(y.Nombre); 
    } 

    public int GetHashCode(RolBase obj) 
    { 
     return obj.Id.GetHashCode()^obj.Nombre.GetHashCode(); 
    } 
} 

2.

var ResultQuery = (from ES in DbMaster.Estudiantes 
           join I in DbMaster.Inscripciones on ES.strCedula equals I.strCedEstud 
           join C in DbMaster.Carreras on I.strCodCarrera equals C.strCodigo 
           where ES.strCedula.Equals(Cedula) 
           select new RolBase { Id = "EST", Nombre = "Estudiante" }).ToList(); 

3.

return ResultQuery.Distinct(new RolBaseComparer()).ToList()