Distinct operator on List<string>
Asked Answered
L

3

11

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?

Lobell answered 26/11, 2012 at 14:2 Comment(6)
What is the type of BatchRouteId ?Residence
A Sample of the data would be nice.Slob
Yes BatchRouteId is a stringLobell
Maybe need trim? var ret = context.XInventTransBackOrder.Where(i => i.BatchRouteId != "").Select(i => i.BatchRouteId.Trim()).Distinct().ToList();Incipient
I tried this out and it worked for me so you got something funky going on. If BatchRouteId is a string and the strings in question are actually identical, then Distinct() would remove them. So either a) BatchRouteId isn't really a string, or b) these identical strings aren't actually identical.Sternforemost
It looks like you're using Linq-to-AX, which version are you using? Distinct seems to be supported in the AX 2012 version according to Microsoft's documentation, but your question doesn't specify exactly which LINQ library you're using here... (see also: msdn.microsoft.com/EN-US/library/jj677293.aspx)Idolatry
I
7

Have you tried

var ret = context.XInventTransBackOrder
    .Where(i => i.BatchRouteId != "")
    .Select(i => i.BatchRouteId)
    .ToList();
ret = ret
    .Distinct()
    .ToList();
Irregular answered 26/11, 2012 at 14:27 Comment(3)
The one hundred dollar question is: Why?Harri
Be careful with this, this can be very expensive, depending on the number of items returned the original list. This first fetches everything to your system and then creates distinct values in memory. What type is your context? Is it converting to some type of AX query or webservice call? Does that API understand the concept of Distinct?Idolatry
My context is a LinqToDynamicsAx context. I get 10 distinct strings. Otherwise I get 116 strings. Not sure if API understands distinct. It changes the C# code to X++Lobell
H
4

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

Harri answered 26/11, 2012 at 14:45 Comment(0)
U
2

X++ does not have a distinct operator. The deferred execution will try to execute on ToList() and will fail because of this.

Ulick answered 6/11, 2017 at 8:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.