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