There are several errors in this code:
Constant strings are used as keys for the inner and outer collections, so even if everything worked, all rows would be selected as a result.
For the solution, it is necessary to use the it object which is provided by default in selectors. It can be omitted if the call goes to the fields of the object, but in this case DataRow does not have the required fields, but there is only an indexer.
Therefore, the selector code should change to
"it[\"t\"]"
where t is the name of the column that is selected.
Next with the result. For the result selector, DynamicLinq provides two default parameters: inner and outer , respectively, store elements of the inner and outer collections appropriate for the join conditions. Thus, the resulting selector may look like this:
"new (outer[\"t\"] as TMP)"
where t is the name of the column that is selected. outer in this case is the DataRow from the first table.
And finally, the main cause of the error:
There are two Join methods in the library.
public static IQueryable Join(this IQueryable outer, IEnumerable inner, string outerKeySelector, string innerKeySelector, string resultSelector, params object[] args) public static IQueryable<TElement> Join<TElement>(this IQueryable<TElement> outer, IEnumerable<TElement> inner, string outerKeySelector, string innerKeySelector, string resultSelector, params object[] args)
As you can see, the first for non-generic IQueryable, the second for generic IQueryable.
The problem is that when you call
newDT.AsEnumerable().AsQueryable()
The resulting collection IQueryable<DataRow> and accordingly selected the second overload. If you pay attention to the return value, you can see that the type of the element coincides with the original type in the collection. Thus, when the result was a collection with a different element type, an error occurred during the cast.
To solve this, you need to use the second overload. To do this, as an option, you can bring the AsQueryable result to a non-generic interface.
((IQueryable)newDT.AsEnumerable().AsQueryable())
As a result, the expression may look like this:
var res2 = ((IQueryable)newDT.AsEnumerable().AsQueryable()).Join(oldDT.AsEnumerable(), "it[\"t2\"]", "it[\"t2\"]", "new (outer[\"t2\"] as TMP)");
newDTandoldDT- Grundy