2012-04-02 2 views
11

У меня есть ПК Enity, у которого есть некоторые свойства, я хотел бы вернуть список отдельных объектов (ПК или сложный тип или что-то еще) на основе свойства, чтобы привязать его к серверным элементам управления, например Выпадающий список . И поскольку мой метод, расположенный в BLL, я не могу вернуть анонимный тип, поэтому я создал Branch ComplexType, который имеет два peroperties.Entity Framework, возвращающая отдельные записи.

Я написал так, но есть 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: Спасибо всем, Это сработало:

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

ли вы имеете в виду, что у вас есть два элемента в 'result' списке который равны как в 'BranchId', так и' BranchName'? Это было бы удивительно, потому что это не должно происходить с вашим примером. – Slauma

+0

Да, вы правильно поняли – Mostafa

+0

Используете ли вы SQL Server? Если да, то какая версия? Если нет, какая база данных? – Slauma

ответ

9

это будет возвращать разные строки для всех столбцов оператор select. Если вы хотите различные строки для конкретного столбца просто указать, что конкретный столбец

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

Если вы хотите, чтобы получить различные значения, основанные на нескольких столбцах, то вы должны создать группу, а затем выбрать первое значение из этой группы. В этом случае вы не будете использовать Distinct, например

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

Спасибо. Первый код не работал, он возвращает повторяющиеся записи, а также мне нужно имя ветки. – Mostafa

+0

@Mostafa, замените BranchId, с BranchName в первом statemet – Habib

+0

Второй тоже не сработал. Он получает ошибку времени компиляции: невозможно преобразовать тип источника System.Collection.Generic.List <...Pc> для целевого типа System.Collection.Generic.List <...Branch> – Mostafa

2

Вы получаете дубликаты, потому что Distinct() не в состоянии признать два ваших сложных объектов Branch как идентичные от их свойств. Он просто сравним для равенства объектов, который вернет false (потому что вы создаете два разных объекта, но с одинаковыми значениями).

Вы можете использовать Distinct(IQueryable, IEqualityComparer), чтобы предоставить свой собственный Comparer или реализовать интерфейс IEquatable.

+0

Пример в вопросе LINQ to Entities ('Distinct'' IQueryable '), а не LINQ to Objects (' Distinct' of 'IEnumerable '). В этом случае сравнение равенства объектов не применяется. – Slauma

+0

Вы правы, хороший звонок. Wrong Distinct() здесь. Но не сможет ли [обеспечить IEqualityComparer] (http://msdn.microsoft.com/en-us/library/bb356803.aspx) решить проблему? – magnattic

+0

Нет, потому что перегрузка 'Distinct', которая принимает' IEqualityComparer', не поддерживается в LINQ to Entities. Я действительно очень смущен, почему пример в вопросе не работает. Я собираюсь проверить это ... – Slauma

2

Я не могу воспроизвести проблему (протестирован с SQL Server 2008 R2 и EF 4.1/DbContext). Запрос в вашем вопросе ...

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

... генерирует следующий 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] 

Это DISTINCT на обеих колонках, и я не получить ожидаемый результат отличный - нет дубликатов в BranchId и BranchName.

+0

Спасибо за ваши усилия. Может быть, это потому, что Key of PC Entity, который является PCId, а не BranchId – Mostafa

1

Это работает для меня.

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() 
Смежные вопросы