[英]Dynamically inject a type in a generic variable in C#
假设我有如下字典。
Dictionary<string, Expression> expressions = new Dictionary<string, Expression> {
{ "Price", (Expression<Func<Phone, double>>) (p => p.Price) },
{ "Brand", (Expression<Func<Phone, string>>) (p => p.Name) }
};
使用实体框架,我可以获得如下所示的结果数据。
BdPhonesDbEntities db = new BdPhonesDbEntities();
IQueryable<Phone> phones = db.Phones.Where(search.GetExpression());
现在,根据用户的选择,我想按价格(两倍)或名称(字符串)对结果进行排序。 使用固定类型(双精度)进行排序时,如下所示。
Expression<Func<Phone, double>> keySelector =
KeySelector<Func<Phone, double>>(expressions, search.OrderBy.PropertyName);
现在,我想在“ double”位置动态插入类型,而不是仅针对double类型排序进行修复。 是否可以有条件地更改此代码的排序?
要一目了然地了解总代码,请检查以下图片或来自Gist
对该函数的调用如下所示:
试试这个实用工具类https://dotnetfiddle.net/T9CFYU
public static class Utility
{
public static Expression<Func<TSource, object>> GetExpressionForProp<TSource>(this TSource source, string propertyName)
{
var param = Expression.Parameter(typeof(TSource), "x");
Expression conversion = Expression.Convert(Expression.Property(param, propertyName), typeof(object));
return Expression.Lambda<Func<TSource, object>>(conversion, param);
}
public static IOrderedQueryable<TSource> OrderByProp<TSource>(this IQueryable<TSource> source, string propertyName)
where TSource : class, new()
{
return source.OrderBy(new TSource().GetExpressionForProp(propertyName));
//or comment where TSource : class, new() and
//var param = Expression.Parameter(typeof(TSource), "x");
//Expression conversion = Expression.Convert(Expression.Property(param, propertyName), typeof(object));
//var shortExpression = Expression.Lambda<Func<TSource, object>>(conversion, param);
//return source.OrderBy(shortExpression);
}
}
一些用法,例如
List<Phone> orderedByPrice = null;
List<Phone> orderedByBrand = null;
/*Try: 1*/
orderedByPrice = Db.Phones.OrderBy(new Phone().GetExpressionForProp("Price")).ToList();
orderedByBrand = Db.Phones.OrderBy(new Phone().GetExpressionForProp("Brand")).ToList();
/*Try: 2*/
orderedByPrice = Db.Phones.OrderByProp("Price").ToList();
orderedByBrand = Db.Phones.OrderByProp("Brand").ToList();
/*Try: 3*/
var expressions = new Dictionary<string, Expression<Func<Phone, object>>>
{
{"Price", (p => p.Price)},
{"Brand", (p => p.Brand)}
};
orderedByPrice = Db.Phones.OrderBy(expressions["Price"]).ToList();
orderedByBrand = Db.Phones.OrderBy(expressions["Brand"]).ToList();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.