2

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?

lhan
  • 4,585
  • 11
  • 60
  • 105
  • 1
    Distinct is not a condition it's an operation. If you were to tell me that you wanted to return the first record for each department of which the employee is a member that would make a lot more sense. You need to rephrase your question and it would also help to supply some demo data and what your desired output is. – JamieSee Dec 21 '12 at 18:54
  • Thanks for the comment. Reading through my question again made it obvious that I needed to re-word it. Please see my updated question with sample data. – lhan Dec 21 '12 at 19:40
  • You're getting an `EnumerableDebugViewEmptyException` while trying to view the content of an empty enumerable in the debugger -- seems reasonable :-) Try converting it to a list with `.ToList()` first. – Matthew Strawbridge Dec 21 '12 at 22:40
  • Thanks! And just out of curiosity is it always safer then to do a `.ToList()` first, and THEN a `.Distinct()`? – lhan Dec 27 '12 at 14:18

3 Answers3

2

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.

Gert Arnold
  • 105,341
  • 31
  • 202
  • 291
0

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).

Community
  • 1
  • 1
Jason Sperske
  • 29,816
  • 8
  • 73
  • 124
  • Thank you for the reply! I re-worded my post, please see the update, I think I've got an entirely different issue now. – lhan Dec 21 '12 at 19:51
0

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());
Evgraf
  • 187
  • 6
  • Thank you for the reply! I re-worded my post, please see the update, I think I've got an entirely different issue now. – lhan Dec 21 '12 at 19:52