Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Distinct operator on List<string>

Tags:

c#

linq

axapta

I'm trying to get distinct string values out of an Ax repository, but I'm getting a lot of identical strings out (strings only contains numbers)

var ret = context.XInventTransBackOrder
    .Where(i => i.BatchRouteId != "")
    .Select(i => i.BatchRouteId)
    .Distinct()
    .ToList();

Where am I going wrong?

like image 400
nk2003dec Avatar asked Nov 26 '12 14:11

nk2003dec


People also ask

What is distinct () in C#?

C# Linq Distinct() method removes the duplicate elements from a sequence (list) and returns the distinct elements from a single data source. It comes under the Set operators' category in LINQ query operators, and the method works the same way as the DISTINCT directive in Structured Query Language (SQL).

What is list distinct?

Returns a list that contains all the values in list list with duplicates removed.

Why distinct is not working in LINQ?

LINQ Distinct is not that smart when it comes to custom objects. All it does is look at your list and see that it has two different objects (it doesn't care that they have the same values for the member fields). One workaround is to implement the IEquatable interface as shown here.


2 Answers

Have you tried

var ret = context.XInventTransBackOrder
    .Where(i => i.BatchRouteId != "")
    .Select(i => i.BatchRouteId)
    .ToList();
ret = ret
    .Distinct()
    .ToList();
like image 164
Jan Lund Madsen Avatar answered Sep 30 '22 17:09

Jan Lund Madsen


If the BatchRouteId was a XElement, for instance, then probably an object reference comparison would be performed. In that case change the code to

var ret = context.XInventTransBackOrder
    .Where(i => i.BatchRouteId != null && !String.IsNullOrEmpty(i.BatchRouteId.Value))
    .Select(i => i.BatchRouteId.Value)
    .Distinct()
    .ToList();

UPDATE #1

Note that some types implement implicit conversions making you think they were another type. You can pass a string to a XName parameter without explicit casting, and the string will automatically be converted to XName.


UPDATE #2

According to a comment of nk2003dec the context is LinqToDynamicsAx. I don't know this interface but probably it does not implement Distinct. What you can to in such a case, is to change the context form a XY-LINQ to Object-LINQ by using the System.Linq.Enumerable.AsEnumerable<TSource> extension method

var ret = context.XInventTransBackOrder
    .Select(i => i.BatchRouteId)
    .Where(id => id != "")
    .AsEnumerable()
    .Distinct()
    .ToList();

I also inverted Select and Where as this simplifies the access to BatchRouteId

like image 26
Olivier Jacot-Descombes Avatar answered Sep 30 '22 18:09

Olivier Jacot-Descombes