Set*_*urg 4 c# linq linq-to-entities expression-trees entity-framework-6
我正在尝试编写LINQ查询以通过字符串值给定的动态属性来orderB。
这是我的原始代码:
Expression<Func<T, dynamic>> orderBy = i => i.GetType().GetProperty("PropertyName").GetValue(null);
Run Code Online (Sandbox Code Playgroud)
当我尝试运行此订单时,出现以下异常:
LINQ to Entities无法识别方法'System.Object GetValue(System.Object)',并且该方法无法转换为商店表达式。
我正在尝试通过创建将给我相同结果的表达式树来解决此问题。该代码应该能够根据参数返回任何类型,但是返回类型有麻烦。如果不转换该值,则会收到另一个错误消息,提示w Nullable DateTime无法转换为Object。这是我到目前为止的代码:
ParameterExpression pe = Expression.Parameter(typeof(T), "s");
Expression<Func<T, dynamic>> orderByExpression = Expression.Lambda<Func<T, dynamic>>(Expression.Convert(Expression.Property(pe, "PropertyName"), typeof(object)), pe);
Run Code Online (Sandbox Code Playgroud)
和我的新例外:
无法将类型'System.Nullable`1 [[System.DateTime]]'强制转换为类型'System.Object'。LINQ to Entities仅支持强制转换EDM基本类型或枚举类型。
我将如何编写此表达式树以返回动态类型?还有在LINQ中应该做的更好的方法吗?
没有模板参数Expression<Func<T, TT>>可以让您代表引用类型和值类型。当然,您可以构建表达式,但是必须通过反射与它们进行交互。
这将正确排序一个集合:
IOrderedEnumerable<TEntityType> SortMeDynamically<TEntityType>(IEnumerable<TEntityType> query, string propertyname)
{
var param = Expression.Parameter(typeof(TEntityType), "s");
var prop = Expression.PropertyOrField(param, propertyname);
var sortLambda = Expression.Lambda(prop, param);
Expression<Func<IOrderedEnumerable<TEntityType>>> sortMethod = (() => query.OrderBy<TEntityType, object>(k => null));
var methodCallExpression = (sortMethod.Body as MethodCallExpression);
if (methodCallExpression == null)
throw new Exception("Oops");
var method = methodCallExpression.Method.GetGenericMethodDefinition();
var genericSortMethod = method.MakeGenericMethod(typeof(TEntityType), prop.Type);
var orderedQuery = (IOrderedEnumerable<TEntityType>)genericSortMethod.Invoke(query, new object[] { query, sortLambda.Compile() });
return orderedQuery;
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您希望使用它IQueryable(例如,如果使用的是EF)
IOrderedQueryable<TEntityType> SortMeDynamically<TEntityType>(IQueryable<TEntityType> query, string propertyname)
{
var param = Expression.Parameter(typeof(TEntityType), "s");
var prop = Expression.PropertyOrField(param, propertyname);
var sortLambda = Expression.Lambda(prop, param);
Expression<Func<IOrderedQueryable<TEntityType>>> sortMethod = (() => query.OrderBy<TEntityType, object>(k => null));
var methodCallExpression = (sortMethod.Body as MethodCallExpression);
if (methodCallExpression == null)
throw new Exception("Oops");
var method = methodCallExpression.Method.GetGenericMethodDefinition();
var genericSortMethod = method.MakeGenericMethod(typeof(TEntityType), prop.Type);
var orderedQuery = (IOrderedQueryable<TEntityType>)genericSortMethod.Invoke(query, new object[] { query, sortLambda });
return orderedQuery;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
784 次 |
| 最近记录: |