Reputation: 2294
I have seen numerous articles which all seem to nibble around the issue I am having but none have provided an actual resolution to the problem. Which is to say they all get me to about 98% solution only to fail in some small detail.
I have an IEnumerable that is collected at run time. This IEnumerable
could be of ANYTHING. I will not know until runtime. I need to sort it however based on a list of propertyNames and sort directions in a List of KeyValuePair objects provided as an argument.
public static void SortData(IEnumerable<dynamic> dataToSort, List<KeyValuePair<string, string>> sortArgs)
{
}
I first get the Type of the IEnumerable
. I have created a method for this. I won't get into this detail here. It's been tested and does return the proper Type.
public static void SortData(IEnumerable<dynamic> dataToSort, List<KeyValuePair<string, string>> sortArgs)
{
Type dataType = TypeService.GetType(data);
}
I then attempt to create an initial IOrderedEnumerable
that I can apply the sortArgs
sort to.
public static void SortData(IEnumerable<dynamic> dataToSort, List<KeyValuePair<string, string>> sortArgs)
{
Type dataType = TypeService.GetType(dataToSort);
// Create IOrderedEnumerable
//
var query = from dataItem in dataToSort
orderby // ?????
select dataItem;
// apply sortArgs to IOrderedEnumerable
//
for(int argIDX = 0; argIDX < sortArgs.Count; argIDX++)
{
var arg = sortArgs[argIDX];
var sortField = arg.Key.Trim();
var sortDirection = arg.Value.Trim().ToUpper();
if(argIDX == 0)
{
if(sortDirection == "DESC")
{
query = query.OrderByDescending(e => e.GetType().GetProperty(sortField).GetValue(e));
}
else
{
query = query.OrderBy(e => e.GetType().GetProperty(sortField).GetValue(e));
}
}
else
{
if(sortDirection == "DESC")
{
query = query.ThenByDescending(e => e.GetType().GetProperty(sortField).GetValue(e));
}
else
{
query = query.ThenBy(e => e.GetType().GetProperty(sortField).GetValue(e));
}
}
}
// After applying the sort retreive the contents
//
dataToSort = query.ToList();
}
It seems by this point I have all the information I should need to sort the original dataToSort
argument. But defining a property to initialize the IOrderedEnumerable
is eluding me.
I have tried a number of different techniques I have read about ...
var query = from dataItem in dataToSort
orderby ( X => 1) //ERR: The type of one of the expressions in the OrderBy clause is incorrect. Type inference failed in the call to 'OrderBy'.
select dataItem;
I have tried to create a new Typed list (since I know the type) so that the expressions in the OrderBy clause could be inferred more accurately.
var typedDataToSort = new List<dataType>(); //ERR: dataType is a variable used like a type
foreach(var item in dataToSort)
{
typedDataToSort.Add( item );
}
I have tried to get the PropertyInfo for a property to sort on..
PropertyInfo propInfo = dataType.GetProperty(dataValueField);
var query = from dataItem in dataToSort
orderby (x => propInfo.GetValue(x, null)) //ERR: The type of one of the expressions in the OrderBy clause is incorrect. Type inference failed in the call to 'OrderBy'. Of couse this could not work since `dataType` is an INSTANCE of
select dataItem;
I have just run out of ideas.
Upvotes: 0
Views: 226
Reputation: 1741
To create an IOrderedIEnumerable
from a List<T>
without manipulating the order you can just execute a noop sort by doing something like this:
var myList = new List<String>(){"test1", "test3", "test2"}
IOrderedIEnumerable<String> query = myList.OrderBy(x => 1);
The same goes for an IEnumerable
- however you must ensure that the underlaying type of IEnumerable
provides stable order for each iteration.
Upvotes: 1