Tôi muốn tạo Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>
từ danh sách các SortingItems
động. tôi có nghĩa là tôi muốn tạo ra các biểu thức sau đây:Tạo Func <IQueryable <TEntity>, IOrderedQueryable <TEntity>> động?
entity => entity.OrderBy(c => c.Id).ThenBy(c => c.Name).ThenByDescending(c => c.LastName)
Sau đây là mã của tôi:
[DataContract]
public class SortingItem
{
[DataMember]
public string PropertySelectorString { get; set; }
[DataMember]
public SortingDirectionsEnum SortingDirections { get; set; }
}
[DataContract]
public enum SortingDirectionsEnum
{
[EnumMember]
Descending = 0,
[EnumMember]
Ascending = 1
}
public Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> GetSortingFunc<TEntity>()
{
_entityType = typeof(TEntity);
_parameterExpression = Expression.Parameter(_entityType, "entity");
_iQueryableParameterExpression = Expression.Parameter(typeof(IQueryable<TEntity>), "f");
MethodInfo orderByMethodInfo = null;
Expression resultExpression = null;
foreach (SortingItem sortingItem in SortingItems)
{
MemberExpression memberExpression = GetLeftSide(sortingItem.PropertySelectorString, _entityType, _parameterExpression); // I'm dead sure about working this line
switch (sortingItem.SortingDirections)
{
case SortingDirectionsEnum.Descending:
orderByMethodInfo = typeof(Queryable).GetMethods().First(method => method.Name == "OrderBy" && method.GetParameters().Length == 2).MakeGenericMethod(_entityType, memberExpression.Type);
if (resultExpression != null)
orderByMethodInfo = typeof(Queryable).GetMethods().First(method => method.Name == "ThenBy" && method.GetParameters().Length == 2).MakeGenericMethod(_entityType, memberExpression.Type);
break;
case SortingDirectionsEnum.Ascending:
orderByMethodInfo = typeof(Queryable).GetMethods().First(method => method.Name == "OrderByDescending" && method.GetParameters().Length == 2).MakeGenericMethod(_entityType, memberExpression.Type);
if (resultExpression != null)
orderByMethodInfo = typeof(Queryable).GetMethods().First(method => method.Name == "ThenByDescending" && method.GetParameters().Length == 2).MakeGenericMethod(_entityType, memberExpression.Type);
break;
}
MethodCallExpression methodCallExpression;
if (resultExpression != null)
// Exception
// An unhandled exception of type 'System.ArgumentException' occurred in System.Core.dll
// Additional information: Incorrect number of arguments supplied for call to method 'System.Linq.IOrderedQueryable`1[ConsoleApplication1.User] ThenBy[User,Int32](System.Linq.IOrderedQueryable`1[ConsoleApplication1.User], System.Linq.Expressions.Expression`1[System.Func`2[ConsoleApplication1.User,System.Int32]])'
methodCallExpression = Expression.Call(orderByMethodInfo, _iQueryableParameterExpression, resultExpression, Expression.Lambda(memberExpression, _parameterExpression));
else
methodCallExpression = Expression.Call(orderByMethodInfo, _iQueryableParameterExpression, Expression.Lambda(memberExpression, _parameterExpression));
resultExpression = Expression.Lambda(methodCallExpression, _iQueryableParameterExpression);
}
Expression<Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>> lambdaExpression = Expression.Lambda<Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>>(resultExpression, _parameterExpression);
return lambdaExpression.Compile();
}
Đó là OK để tạo {f.OrderBy(entity => entity.Id)}
hoặc {f.ThenBy(entity => entity.Name)}
riêng rẽ, nhưng tôi nhận được ngoại lệ ở dòng sau
methodCallExpression = Expression.Call(orderByMethodInfo, _iQueryableParameterExpression, resultExpression, Expression.Lambda(memberExpression, _parameterExpression));
Tôi nên sử dụng Expression.Call
để kết hợp như thế nào {f.OrderBy(entity => entity.Id)}
với {f.ThenBy(entity => entity.Name)}
, ....?
bạn có thể giải thích những gì bạn cần là gì? Có thể có một giải pháp dễ dàng hơn cho "vấn đề lớn hơn" của bạn ... – ChrFin
Tôi đã tạo 'SortingItems' trong ứng dụng khách và gửi nó đến dịch vụ. Trong Service tôi muốn tạo phân loại 'func' để sử dụng trong khung thực thể –