【问题标题】:Linq Distinct() by name for populate a dropdown list with name and valueLinq Distinct() 按名称填充带有名称和值的下拉列表
【发布时间】:2009-05-26 19:08:50
【问题描述】:

我正在尝试用制药公司(如 Bayer、Medley 等)填充下拉列表。而且,我从 DB 获取这些名称,这些名称在 DB 中重复,但 ID 不同。

我正在尝试使用 Linq Distinct(),但我不想使用相等比较器。还有其他方法吗?

我的下拉列表必须填写公司的id和名称。

我正在尝试类似的东西:

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

这是在 ddl 中显示重复的公司。

谢谢!

【问题讨论】:

  • 如果一家公司以不同的 id 出现多次,而您希望它们只出现一次,应该显示什么 id?首先?没关系?

标签: c# linq-to-sql distinct


【解决方案1】:

以下表达式将仅选择不同的公司并返回第一次出现的公司及其 id。

partnerService.SelectPartners().GroupBy(p => p.Name).Select(g => g.First());

【讨论】:

  • 嗨丹尼尔!这正是我所需要的!谢谢! :-)
  • 当我这样做时: dgvRecords.DataSource = (from g in dbContext.records select g).GroupBy(g => g.ID).Select(g => g.FirstOrDefault());我得到:消息=不支持指定的方法。 Source=MySql.Data.Entity
  • @AndreMiranda 您可以在主 linq 选择的末尾使用 groupbyselect,这非常有用@Daniel Brückner, TNX
  • 对于 VB.net 人,使用 .GroupBy(Function(p) p.Name).Select(Function(g) g.First()) 还要确保导入 System.Linq 否则你赢了'在 IGrouping 类的 select 调用中不获取 First 函数
  • 只是因为我一开始不明白这一点,它所做的是按名称对列表进行分组 - [("john", "john"),("george", "george", "george")] - 然后只选择每个内部组中的第一个并将它们放在一个列表中。
【解决方案2】:
var distinctCompanies = Companies
  .GroupBy(c => c.CompanyName)
  .Select(g => g.First());

【讨论】:

  • 很抱歉,'g' 来自哪里?
  • @StarCub Companies 是一个 IEnumerable。 GroupBy 接受并返回 IEnumerable>。 Select 中的每个项目都是一个 IGrouping。我使用了不同的名称以使类型的差异更加明显。
【解决方案3】:

Distinct 作用于整个选择。如果您在选择中包含 c.codPartner,并且同一 c.name 有两个不同的 c.codPartner 值,那么您将看到具有相同 c.name 的两行。

【讨论】:

    【解决方案4】:

    我认为你不能用匿名类来做到这一点,但如果你创建了一个像这样的数据对象

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

    【讨论】:

      【解决方案5】:

      如果您没有指定 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();
      

      【讨论】:

      • ReferenceEquals 不比较哈希码,它比较引用...只有当两个引用指向同一个实例时才会返回 true
      【解决方案6】:

      如果您不告诉 Distinc(通过 IEqualityComparer)使用另一种方法,Distinc 将使用 GetHashCode。 您可以使用通用的相等比较器,如下所示:

      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);
              });
            }
      }
      

      【讨论】:

        【解决方案7】:

        只需使用其他重载之一将您自己的比较器传递给 Distinct 方法。

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

        【讨论】:

        • 它不会改变任何东西......如果有几个公司名称相同但id不同,你会如何选择使用的id?
        • 我同意 - 选择 ID 会是个问题。如果您想为每个 ID 指定一个特定的 ID,则使用带有 EqualityComparer 的 distinct 可能不是可行的方法。另外,请记住这里的否决票,原始问题没有说明为不同结果中的每个项目选择特定 ID...
        猜你喜欢
        • 2013-02-27
        • 2014-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多