我有一个扩展方法,尝试使用IComparer类型的类对多个列对数据表的行进行排序,以进行至少一个排序。
使用仅在运行时知道其名称和数据类型的列创建数据表。排序字符串(“Title ASC,PostedDate DESC”)也在运行时创建。
所以说我的表有列:ID,Name,PostedDate,Num1。我的排序字符串是“PostedDate DESC,Name ASC”,在字符串列“Name”的排序过程中,我想使用自定义类
NaturalSortComparer : IComparer<string>
如果列的dataType等于TComparerType,我试图在OrderBy调用中使用指定的IComparer对象,但我想“不能从我的用法中推断出类型参数”。
有没有人知道我可以解决这个问题的方法?提前谢谢。
public static EnumerableRowCollection<DataRow> OrderBy<TComparerType>(
this EnumerableRowCollection<DataRow> rows, DataTable table, string orderBy, IComparer<TComparerType> comparer)
{
if (table == null || string.IsNullOrWhiteSpace(orderBy))
{
return rows;
}
OrderedEnumerableRowCollection<DataRow> orderedRows = null;
foreach (string sortString in orderBy.Split(new[] { "," }, StringSplitOptions.None))
{
var trimmedSortString = sortString.Trim();
int directionIndex = trimmedSortString.IndexOf(" DESC", StringComparison.OrdinalIgnoreCase);
bool isDescending = directionIndex != -1;
string columnName = isDescending ? trimmedSortString.Substring(0, directionIndex) : trimmedSortString;
Type columnType = table.Columns[columnName].DataType;
Func<DataRow,dynamic> selectorFunc = (row => RowSelectors[columnType](row, columnName));
Type comparerTypeParameter = comparer == null ? null : typeof(TComparerType);
if (orderedRows == null)
{
if (columnType == comparerTypeParameter)
{
orderedRows = isDescending
? rows.OrderByDescending(selectorFunc, comparer)
: rows.OrderBy(selectorFunc, comparer);
}
else
{
orderedRows = isDescending
? rows.OrderByDescending(selectorFunc)
: rows.OrderBy(selectorFunc);
}
}
else
{
if (columnType == comparerTypeParameter)
{
orderedRows = isDescending
? orderedRows.ThenByDescending(selectorFunc, comparer)
: orderedRows.ThenBy(selectorFunc, comparer);
}
else
{
orderedRows = isDescending
? rows.OrderByDescending(selectorFunc)
: rows.OrderBy(selectorFunc);
}
}
}
return orderedRows ?? rows;
}
private static readonly Dictionary<Type, Func<DataRow, string, dynamic>> RowSelectors =
new Dictionary<Type, Func<DataRow, string, dynamic>>
{
{typeof(string), (row,colName)=>row.Field<string>(colName)},
{typeof(decimal), (row,colName)=>row.Field<decimal>(colName)},
{typeof(int), (row,colName)=>row.Field<int>(colName)},
{typeof(short), (row,colName)=>row.Field<short>(colName)},
{typeof(float), (row,colName)=>row.Field<float>(colName)},
{typeof(double), (row,colName)=>row.Field<double>(colName)},
{typeof(bool), (row,colName)=>row.Field<bool>(colName)},
{typeof(DateTime), (row,colName)=>row.Field<DateTime>(colName)},
{typeof(TimeSpan), (row,colName)=>row.Field<TimeSpan>(colName)}
};
答案 0 :(得分:0)
当你改变
Func<DataRow, dynamic> selectorFunc = (row => RowSelectors[columnType](row, columnName));
到
Func<DataRow, TComparerType> selectorFunc = (row => RowSelectors[columnType](row, columnName));
你的代码将编译。