2012-04-02 16 views
11

Ho un PC Enity che ha alcune proprietà, vorrei restituire un elenco di oggetti distinti (PC o tipo complesso o qualsiasi altra cosa) basato su una proprietà per collegarlo ai controlli del server come Menu `A tendina . E poiché il mio metodo situato in BLL non può restituire un tipo anonimo, così ho creato un Branch ComplexType che ha due peroperties.Entity Framework restituisce record distinti problema

ho scritto come questo, ma si hanno record repeative:

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

Edit: Grazie a tutti, questo ha funzionato:

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

vuoi dire che ci sono due elementi della lista 'result' quale sono uguali sia in 'BranchId' che in' BranchName'? Ciò sarebbe sorprendente perché ciò non dovrebbe accadere con il tuo esempio. – Slauma

+0

Sì Hai capito bene – Mostafa

+0

Usi SQL Server? Se sì, quale versione? Se no, quale database? – Slauma

risposta

9

questo restituirà righe distinte per tutte le colonne l'istruzione select. Se si desidera righe distinte per una particolare colonna solo specificare che particolare colonna

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

Se si desidera ottenere valori distinti in base a più colonne, quindi è necessario creare un gruppo e poi scegliere il primo valore da quel gruppo. In questo caso non utilizzerà distinto, per esempio

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

Grazie. Il primo codice non ha funzionato, restituisce i record ripetitivi e ho bisogno di branchName. – Mostafa

+0

@Mostafa, sostituire BranchId, con BranchName nella prima statemet – Habib

+0

Anche il secondo non ha funzionato. Si ottiene errore in fase di compilazione: Impossibile convertire il tipo di origine System.Collection.Generic.List <...Pc> nel tipo di destinazione System.Collection.Generic.List <...Branch> – Mostafa

2

È possibile ottenere i duplicati perché Distinct() è in grado di riconoscere due dei vostri oggetti Branch complessi come identici dalle loro proprietà. Verrà semplicemente confrontato per l'uguaglianza dell'oggetto, che restituirà false (poiché si creano due oggetti diversi, ma con gli stessi valori).

È possibile utilizzare Distinct(IQueryable, IEqualityComparer) per fornire il proprio comparatore o implementare l'interfaccia IEquatable.

+0

L'esempio nella domanda è LINQ to Entities ('Distinct' of 'IQueryable '), non LINQ to Objects (' Distinct' of' IEnumerable '). Il confronto sull'uguaglianza dell'oggetto non si applica in questo caso. – Slauma

+0

Hai ragione, buona telefonata. Wrong Distinct() qui. Ma non [fornire un IEqualityComparer] (http://msdn.microsoft.com/en-us/library/bb356803.aspx) risolve ancora il suo problema? – magnattic

+0

No, perché il sovraccarico di 'Distinct' che accetta' IEqualityComparer' non è supportato in LINQ su Entities. In realtà sono molto confuso perché l'esempio nella domanda non funziona. Lo testerò ... – Slauma

2

Non riesco a riprodurre il problema (testato con SQL Server 2008 R2 e EF 4.1/DbContext). La query nella tua domanda ...

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

... genera il seguente 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] 

Si tratta di un DISTINCT su entrambe le colonne e ottengo il risultato netto atteso - duplicati in BranchId e BranchName.

+0

Grazie per il tuo impegno, Forse è perché la Chiave di PC Entity che è PCId e non BranchId – Mostafa

1

Questo funziona per me.

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() 
Problemi correlati