Reputation: 3180
Ive got the following query that binds to a 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();
}
For some reason it still ourputs 2 rows that are visually the same. It might be the case that there are two enitites in the CRM with the same name. But, if Im using distinct on the query and only returning the 'py3_brancharea' then surely the Distinct should be run on the actual records returned?
So, this suggests to me -and my limited LINQ knowledge- that its because of the line:
BranchTagCode = t.py3_BranchArea
But, this needs to be called to make it possible to call the FormattedValues.
How then do I get a distinct set of results based purely on 'BranchTag' ?
Upvotes: 2
Views: 3763
Reputation: 1698
If Distinct()
is not working it is possibly a problem with the particular classes gethashcode()
or equals()
override methods, which are either not set up correctly or omitted entirely. In a custom class you will most likely need to specify these overrides to get Distinct()
and other like methods to function correctly.
You could try to use a where or any clause to differentiate between duplicates as well. Which could be a work around for the Distinct()
issues.
To further explain how to set up the Distinct()
Method with custom classes. You will need to within the class that you are searching through set the override methods GetHashCode()
and Equals()
. These or Object level methods that should be in every single class no matter what. To start head to the class in question and type this:
public override bool Equals(object obj)
then
public override int GetHashCode()
Lets say you have this simple class before the overrides:
class foo{
int H {get;set;}
public foo(int _h){
H = _h;
}
}
It would now look like this:
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;
}
}
Now you could use Distinct()
on Ienumerable types containing the foo
class like so:
List<foo> FooList = new List<foo>(Collection of 9 Foos);
var res = FooList.Distinct();
Upvotes: 4
Reputation: 2380
Another possibility it that the Entity Object has a define key that is not unique.
Upvotes: 0
Reputation: 3209
I changed my code from
.Distinct().ToList();
to
.ToList().Distinct().ToList();
and now it's able to avoid the duplicate. Not sure what's the reason behind.
Upvotes: 0
Reputation: 11105
Another, much more simple way that worked for me, but may not work in all situations, is using this guys method ( GroupBy()
and First()
):
Finding Distinct Elements in a List
He creates a List<Customer> customers
with FirstName
and LastName
. Then groups them all by FirstName
and grabs the first element from each group!
`
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"}
};
`
Then:
`
var distinctCustomers = customers.GroupBy(s => s.FirstName)
.Select(s => s.First());
`
In my situation, I had to use FirstOrDefault()
though.
Upvotes: 2
Reputation: 8488
The default equality comparison for anonymous types is case sensitive. Do the returned values you expect have different casing? As Matt suggested you may want to look at a custom IEqualityComparer implementation on a custom class otherwise.
Upvotes: 0
Reputation: 3014
Is it possible that the two results are different, do they have the same branch tag code and branch tag?
You could implement a custom equality comparer and pass it to distinct() so that it only compares the field that you want? it's a bit more difficult because of the anonymous type in your select statement, but this answer has a way around that.
Upvotes: 0