2012-04-02 9 views
11

Mam Enity PC, które mają pewne właściwości, chciałbym zwrócić listę odrębnych Object (PC lub Complex Type lub cokolwiek innego) na podstawie właściwości w celu związania go do kontroli serwera, takich jak Lista rozwijana . Ponieważ moja metoda znajduje się w BLL, nie mogę zwrócić anonimowego typu, więc stworzyłem Branch Complex Type, który ma dwie właściwości peroperties.Entity Framework zwracające odrębne rekordy wydanie

pisałem jak to ale mają repeative rekordy:

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

Edit: Dziękuję wszystkim, to pracował:

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

Czy to znaczy, że masz dwa elementy w 'result' listy który są równe w 'BranchId' i 'BranchName'? Byłoby to zaskakujące, ponieważ nie powinno to mieć miejsca w przypadku twojego przykładu. – Slauma

+0

Tak Masz rację – Mostafa

+0

Czy używasz serwera SQL? Jeśli tak, która wersja? Jeśli nie, która baza danych? – Slauma

Odpowiedz

9

ten powróci odrębne wiersze dla wszystkich kolumn w instrukcja select. Jeśli chcesz odrębne wiersze dla danej kolumnie tylko określić, że danej kolumnie

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

Jeśli chcesz otrzymać różne wartości na podstawie wielu kolumn, a następnie trzeba utworzyć grupę, a następnie wybrać pierwszą wartość z tej grupy. W takim przypadku nie będzie wykorzystywać różne, na przykład

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

Dzięki. Pierwszy kod nie zadziałał. Zwraca rekordy, a ja potrzebuję nazwy oddziału. – Mostafa

+0

@Mostafa, zamień BranchId, z BranchName na pierwszą statemet – Habib

+0

Druga też nie działała. Występuje błąd czasu kompilacji: Nie można przekonwertować typu źródłowego System.Collection.Generic.List <...Pc> na typ docelowy System.Collection.Generic.List <...Branch> – Mostafa

2

uzyskać duplikaty bo Distinct() nie jest w stanie rozpoznać swoich dwóch złożonych obiektów oddział jako identyczne z ich właściwości. Będzie po prostu porównywać dla równości obiektów, która zwróci wartość false (ponieważ tworzysz dwa różne obiekty, ale z tymi samymi wartościami).

Możesz użyć Distinct(IQueryable, IEqualityComparer), aby podać swój własny interfejs lub wprowadzić interfejs IEquatable.

+0

Przykład w pytaniu to LINQ to Entities ('Distinct' of' IQueryable '), a nie LINQ to Objects (' Distinct' of 'IEnumerable '). Porównanie równości obiektów nie ma w tym przypadku zastosowania. – Slauma

+0

Masz rację, dobre połączenie. Wrong Distinct() tutaj. Ale czy [dostarczając IEqualityComparer] (http://msdn.microsoft.com/en-us/library/bb356803.aspx) nadal nie naprawi problemu? – magnattic

+0

Nie, ponieważ przeciążenie 'Distinct', które przyjmuje' IEqualityComparer' nie jest obsługiwane w LINQ do Entities. W rzeczywistości jestem bardzo zdezorientowany, dlaczego przykład w pytaniu nie działa. Mam zamiar przetestować to ... – Slauma

2

Nie mogę odtworzyć problemu (przetestowany z SQL Server 2008 R2 i EF 4.1/DbContext). Zapytanie w swoim pytaniu ...

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

... generuje następujący 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] 

Jest wyraźny na obu kolumnach i uzyskać oczekiwany wynik odrębną - bez duplikatów w BranchId i BranchName.

+0

Dziękuję za twój wysiłek, Może to dlatego, że Klucz Podmiotu PC, który jest PCId, a nie BranchId – Mostafa

1

To działa dla mnie.

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