OK, I got a solution:
It was very obvious that he had something like System.DbNull
Firstly, because in my DataTable I only had rows, and I received an error message:
Object must be of type "string"
But how can a string not contain a string of type? Of course, only if it is DbNull.
And if you have two adjacent DbNull.Values, you will of course get:
At least one object must implement IComparable
Since DbNull does not implement IComparable.
In the end, the funny thing is that this only happened when the sort column was a column with NULL values, but it worked fine if it was a column with no NULL values.
Since the table itself contains all null values, regardless of order, it would be illogical that CopyToDataTable sometimes does not work, because it copied all the values ββevery time, regardless of order.
The only logical conclusion was that OrderBy does NOT start when it is called in code, but only when some method actually used the data created by OrderBy.
A quick google search led me to this http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx
Of these, only the first few lines had to be read to find out what the problem was:
This post covers one of the most important and often misunderstood LINQ features. Understanding the delayed execution ritual of passage that LINQ developers must go through before they can hope to use the full power of this technology.
So, it became clear to me that I just passed the right of passage :)
Obviously, the disadvantage is that e.MoveNext() compares which is not executed on DbNull when ordering triggers, because DbNull, as said, does not implement IComparable.
Ironically, a datatable can also be sorted using a select statement that I did not know initially (in the end, I would expect the "order" method to be called "order" and not "select" ..) So I just changed OrderBy in Linq.Dynamic to
public static IQueryable OrderBy(this IQueryable source, string ordering, params object[] values) { if (source == null) throw new ArgumentNullException("source"); if (ordering == null) throw new ArgumentNullException("ordering"); if (object.ReferenceEquals(source.ElementType, typeof(System.Data.DataRow))) { using (DataTable dt = source.Cast<System.Data.DataRow>().CopyToDataTable()) { return dt.Select("", ordering).AsQueryable(); }
And voila, the error has disappeared.
And since it can only be filtered using Select alone more efficiently than using Linq.Dynamic (which is about 3 copies of all data), I decided to completely abandon Linq.Dynamic.
I am still using Linq and will skip, but in the future I will, of course, no longer use Linq at all.
Delayed execution is directly dangerous because it leads to very terrible errors.
All that boooom needs is a null value in the wrong place or a missing interface (and a missing check or no constraint for generics in this case) ...