Reputation: 4635
Consider the following class:
Public Class Employee
Public State As String
Public Dept As String
Public Status as Integer
End Class
I need to query a distinct value from a listEmployees
which is four records:
oEmp = New Employee
oEmp.Dept = "HR"
oEmp.State = "Kansas"
oEmp.Status = 1
listEmployees.Add(oEmp)
oEmp = New Employee
oEmp.Dept = "HR"
oEmp.State = "Texas"
oEmp.Status= 3
listEmployees.Add(oEmp)
oEmp = New Employee
oEmp.Dept = "HR"
oEmp.State = "Texas"
oEmp.Status= 5
listEmployees.Add(oEmp)
oEmp = New Employee
oEmp.Dept = "DEV"
oEmp.State = "Texas"
oEmp.Status= 7
listEmployees.Add(oEmp)
What I need the query to do is return distinct Deparments where State
= 'Texas'. But I need be able to add multiple cases to the Where
clause. So another query might need to return distinct Status's where State
= 'Texas', and Dept
= 'HR'.
There will always be only one field which I need distinct.
So the results to my first query example would be "HR" and "DEV" because those are the distinct Departments that have "Texas" as the State. The results to the second query would be "3" and "5" because those are the distinct Status's where the State is "Texas" and the Department is "HR".
UPDATE:
Here's what I've got working for Query #1:
Dim test = (From emp As Employee In listEmployees
Where emp.State = "Texas"
Select emp.Dept).Distinct()
However, if I specify something for State
that doesn't exist, such as "TTexas", I get the following exception (the code doesn't blow up but if I inspect the test
variable in Visual Studio after this line executes, I get this):
Exception of type 'System.Linq.SystemCore_EnumerableDebugViewEmptyException' was thrown. at System.Linq.SystemCore_EnumerableDebugView`1.get_Items()
Is this normal LINQ behavior?
Upvotes: 2
Views: 3755
Reputation: 109185
After your edit (new issue). Yes this is "normal" (as in: intended) behaviour. See the code of get_Items
:
public T[] Items
{
get
{
List<T> tempList = new List<T>();
IEnumerator<T> currentEnumerator = this.enumerable.GetEnumerator();
if (currentEnumerator != null)
{
for(count = 0; currentEnumerator.MoveNext(); count++)
{
tempList.Add(currentEnumerator.Current);
}
}
if (count == 0)
{
throw new SystemCore_EnumerableDebugViewEmptyException();
}
cachedCollection = new T[this.count];
tempList.CopyTo(cachedCollection, 0);
return cachedCollection;
}
}
I wonder why a debug view should throw an exception and not just show "count = 0" or something, but that's probably just ignorance.
Upvotes: 2
Reputation: 187
Create your own comparer in order to detect items equality
public class Comparer : IEqualityComparer<Employee>
{
public bool Equals(Employee x, Employee y)
{
throw new NotImplementedException();
}
public int GetHashCode(Employee obj)
{
throw new NotImplementedException();
}
}
And use it
... .Distinct(new Comparer());
Upvotes: 0
Reputation: 30436
Distinct means across all elements of a row. If you have two rows where all returned elements are the same, distinct will reduce it to one row, but if even one element is different then both rows will be returned after distinct. You could override this (as seen here and in Evgraf's answer) of course. Grouping operators are more likely what you are looking for (here is an example in VB.net).
Upvotes: 0