Linq Distinct () по имени для заполнения выпадающего списка с именем и значением - PullRequest
33 голосов
/ 26 мая 2009

Я пытаюсь заполнить выпадающий список фармацевтическими компаниями, такими как Bayer, Medley и т. Д. И я получаю имена тезисов из DB, а имена тезисов повторяются в DB, ​​но с разными идентификаторами.

Я пытаюсь использовать Linq Distinct (), но я не хочу использовать средство сравнения равенства. Есть ли другой способ?

Мой выпадающий список должен быть заполнен идентификатором и названием компании.

Я пытаюсь что-то вроде:

var x = _partnerService
           .SelectPartners()
           .Select(c => new {codPartner = c.codPartner, name = c.name})
           .Distinct();

Это показывает повторные компании в ddl.

спасибо!

Ответы [ 7 ]

76 голосов
/ 26 мая 2009

Следующее выражение выберет только отдельные компании и вернет первый случай с его идентификатором.

partnerService.SelectPartners().GroupBy(p => p.Name).Select(g => g.First());
17 голосов
/ 26 мая 2009
var distinctCompanies = Companies
  .GroupBy(c => c.CompanyName)
  .Select(g => g.First());
3 голосов
/ 26 мая 2009

Отличная работа на весь выбор. Если вы включите c.codPartner в select, и для одного и того же c.name есть два разных значения c.codPartner, то вы увидите две строки с одинаковым c.name.

2 голосов
/ 26 мая 2009

Я не думаю, что вы можете сделать это с анонимным классом, но если вы создали объект данных, такой как

    class Foo
{
    private int _ID;

    public int ID
    {
        get { return _ID; }
        set { _ID = value; }
    }
    private string _Name;

    public string Name
    {
        get { return _Name; }
        set { _Name = value; }
    }

}

вы можете создать объект сравнения, например

    class FooComparer : IEqualityComparer<Foo>
{


    public bool Equals(Foo x, Foo y)
    {
        return x.Name == y.Name;
    }

    public int GetHashCode(Foo obj)
    {
        return obj.GetHashCode();
    }

}
1 голос
/ 26 мая 2009

Distinc будет использовать GetHashCode, если вы не скажете ему (через IEqualityComparer) использовать другой метод. Вы можете использовать универсальный компаратор равенства, например:

public class GenericEqualityComparer<T> : IEqualityComparer<T>
{    
    private Func<T, T, Boolean> comparer;    

    public GenericEqualityComparer(Func<T, T, Boolean> comparer)    
    {        
        this.comparer = comparer;    
    }    

    #region IEqualityComparer<T> Implementation

    public bool Equals(T x, T y)    
    {        
        return comparer(x, y);    
    }    

    public int GetHashCode(T obj)    
    {
        return obj.GetHashCode();  
    }    

    #endregion
}

и затем используйте вот так (kindof)

public static IEqualityComparer<YourType> MyComparer
{
   get
     {
      return new GenericEqualityComparer<YourType>((x, y) =>
       {
          return x.name.Equals(y.name);
        });
      }
}
1 голос
/ 26 мая 2009

Если вы не укажете параметр IEqualityComparer, он будет просто использовать Object.ReferenceEquals, который просматривает значение GetHashKey объектов. Для анонимных типов они уникальны.

Теперь решить это немного сложно, поскольку вы не можете написать IEqualityComparer для анонимного типа. Итак, вы должны создать реальный тип для задачи:

class Partner
{
    public int codPartner {get; set;}
    public string name {get; set;}
    public override int GetHashCode() { return name .GetHashCode();}
}

var x = _partnerService.SelectPartners()
        .Select(c => new Partner {codPartner = c.codPartner, name = c.name})
        .Distinct();
0 голосов
/ 26 мая 2009

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

(extension) IQueryable<T> IQueryable<T>.Distinct( IEqualityComparer<T> comparer )
...