2

我得到了绑定到 DropDownList 的以下查询;

if (!Page.IsPostBack)
        {
            var branchTags =
                (
                    from t in context.ContactSet
                    orderby t.py3_BranchArea
                    where t.py3_BranchArea != null
                    select new
                    {
                        BranchTagCode = t.py3_BranchArea,
                        BranchTag = (t.FormattedValues != null && t.FormattedValues.Contains("py3_brancharea") ? t.FormattedValues["py3_brancharea"] : null)
                    }
                ).Distinct();
            ddlBranchTags.DataSource = branchTags;
            ddlBranchTags.DataBind();
        }

由于某种原因,它仍然输出 2 行在视觉上是相同的。CRM 中可能有两个同名的实体。但是,如果我在查询中使用 distinct 并且只返回 'py3_brancharea' 那么肯定应该在返回的实际记录上运行 Distinct 吗?

所以,这向我表明——以及我有限的 LINQ 知识——这是因为这条线:

BranchTagCode = t.py3_BranchArea

但是,需要调用它才能调用 FormattedValues。

那么我如何获得完全基于 'BranchTag' 的一组不同的结果?

4

6 回答 6

3

如果Distinct()不起作用,则可能是特定类gethashcode()equals()覆盖方法存在问题,这些方法要么设置不正确,要么完全省略。在自定义类中,您很可能需要指定这些覆盖以获取Distinct()和其他类似方法才能正常运行。

您也可以尝试使用 where 或 any 子句来区分重复项。这可能是解决这些Distinct()问题的方法。

进一步解释如何使用自定义类设置Distinct()方法。您将需要在您正在搜索的类中设置覆盖方法GetHashCode()Equals(). 无论如何,这些或对象级别的方法都应该存在于每个类中。要开始前往相关课程并输入以下内容:

public override bool Equals(object obj) 然后 public override int GetHashCode()

假设您在覆盖之前有这个简单的类:

class foo{
   int H {get;set;}
   public foo(int _h){
        H = _h;
   }
}

它现在看起来像这样:

class foo{
   int H {get;set;}
   int K {get;set;}

   public override bool Equals(object obj){
         if(obj == null) return false;
         foo test = (foo)obj);
         if(test == null) return false;
         
         if(this.H == obj.H && this.K == obj.K) return true;
   }
   public override int GetHashCode(){
         int hashH = H.GetHashCode();
         int hashK = K.GetHashCode();

         return hashH ^ hashK;
   }

   public foo(int _h){
        H = _h;
   }
}

现在您可以在包含类Distinct()的 Ienumerable 类型上使用,如下所示:foo

 List<foo> FooList = new List<foo>(Collection of 9 Foos);
 var res = FooList.Distinct();
于 2013-04-30T00:22:47.823 回答
1

另一种对我有用但可能不适用于所有情况的更简单的方法是使用这种方法(GroupBy()First()):

在列表中查找不同的元素

他创建了一个List<Customer> customerswithFirstNameLastName。然后将它们全部分组FirstName并从每个组中获取第一个元素!

`
List< Customer > customers = new List< Customer >;
{
    new Customer {FirstName = "John", LastName = "Doe"},
    new Customer {FirstName = "Jane", LastName = "Doe"},
    new Customer {FirstName = "John", LastName = "Doe"},
    new Customer {FirstName = "Jay",  LastName = null},
    new Customer {FirstName = "Jay",  LastName = "Doe"}
};
`

然后:

`
var distinctCustomers = customers.GroupBy(s => s.FirstName)
                                 .Select(s => s.First());
`

在我的情况下,我不得不使用FirstOrDefault()

于 2014-11-28T18:36:25.313 回答
0

是否有可能这两个结果不同,它们是否具有相同的分支标记代码和分支标记?

您可以实现自定义相等比较器并将其传递给 distinct() 以便它只比较您想要的字段?由于您的 select 语句中的匿名类型,这有点困难,但这个答案有办法解决这个问题。

于 2013-04-30T01:01:48.077 回答
0

匿名类型的默认相等比较区分大小写。您期望的返回值是否有不同的大小写?正如马特建议的那样,您可能希望在自定义类上查看自定义 IEqualityComparer 实现。

于 2013-04-30T08:20:18.947 回答
0

我改变了我的代码

.Distinct().ToList();

.ToList().Distinct().ToList();

现在它能够避免重复。不知道背后的原因是什么。

于 2019-04-09T09:22:57.317 回答
0

另一种可能性是实体对象具有不唯一的定义键。

于 2019-10-03T13:59:50.413 回答