尽管Distinct(),LINQ查询返回重复

时间:2013-04-30 00:18:57

标签: c# linq linq-to-entities dynamics-crm-2011 dynamics-crm-online

我有以下查询绑定到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();
        }

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

所以,这对我 - 以及我有限的LINQ知识 - 表明它是因为行:

BranchTagCode = t.py3_BranchArea

但是,需要调用它来调用FormattedValues。

如何根据'BranchTag'获得一组独特的结果?

6 个答案:

答案 0 :(得分: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();

答案 1 :(得分:1)

另一个更简单的方法对我有用,但可能无法在所有情况下使用,使用这个方法(GroupBy()First()):

Finding Distinct Elements in a List

他使用List<Customer> customersFirstName创建LastName。然后按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()

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

我从

更改了代码
.Distinct().ToList();

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

,现在可以避免重复。不知道是什么原因。

答案 5 :(得分:0)

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