我收到以下错误:
the type arguments for method 'Queryable.OrderBy<TSource,TKey>(
IQueryable<TSource>, Expression<Func<TSource,TKey>>)
cannot be inferred from the useage.
如何修改Me.GetOrder()
或myOrderByVariable
声明,以便创建一个作为OrderBy()
参数的变量,而不使用自定义扩展方法? 此代码只是一个测试。我需要将变量发送到外部存储库。
void Main()
{
// Assemble
string property = "sku";
var propertyType = Product.GetType().GetProperty(property).GetType();
var entityType = Product.GetType();
// Act
// TODO: begin part to change
var myOrderByVariable = Me.GetOrder(Product.GetType(), propertyType, property );
// end part to change
// Assert
Product
.OrderBy( myOrderByVariable )
.Skip(10).Take(10)
.Dump();
}
public static class Me
{
// TODO: begin part to change
public static Expression<Func<TS, TK>>
GetOrder<TS,TK>(TS entity, TK propType, string propertyName)
{
//Create x=>x.PropName
var propertyInfo = typeof(TS).GetProperty(propertyName);
ParameterExpression arg = Expression.Parameter(typeof(TS), "x");
MemberExpression property = Expression.Property(arg, propertyName);
var selector = Expression.Lambda<Func<TS,TK>>(
property, new ParameterExpression[] { arg });
return selector;
}
// end part to change
}
其余部分是对问题的回答。
添加编辑1:产品碰巧是使用实体框架从数据库表驱动的POCO:
public partial class Product
{
public long sku { get; set; }
public string name { get; set; }
public bool active { get; set; }
public int retailpriceqty { get; set; }
public decimal retailprice { get; set; }
}
附加编辑2:我如何使用URF Unit of Work & Repositories Framework
中的变量// in my ASP.NET MVC Controller
// Restful Post instead of Get because query object creates the response
[Route("Product")][HttpPost]
public IEnumerable<ProductVM> GetProductVM(
[FromBody] QueryObjectVM query )
{
// QueryObjectVM has a FilterBy string (predicate), OrderBy string,
// Select string (projection), page size, and page number
// Select is a TODO until I get dynamic mapping working, which is next
var queryby = QueryService.CleanupQuery( query);
var filterby = Spec.FilterBy<Product>( queryby.FilterBy);
var orderby = Spec.OrderBy<Product>( queryby.OrderBy);
// Could possibly inject .OrderBy("sku") via Dynamic Linq,
// but would repository understand it?
var result = _productService
.Query( filterby )
.OrderBy( o => o.OrderBy( orderby) ) // .OrderBy ( o => o.OrderBy(oo => oo.sku))
.Select( ProductVM.Map)
.Skip( (queryby.page - 1) * queryby.pageSize)
.Take( queryby.pageSize)
;
return result;
}
编辑:这适用于Microsoft Dynamic Linq扩展方法,但我们需要非扩展方法答案。 NetMage在某一点上回答了一个返回object
数据类型的方法,该数据类型对于从string
等对象派生的变量非常有效,但long
和int
仍然失败。也许使用dynamic
代替object
作为方法返回类型会起作用吗?可能的?
var result = _Product
.Query(filter)
.OrderBy(o => o.OrderBy(s.Count > 0 ? s[0] : "first_field")
.OrderBy(s.Count > 1 ? s[1] : "second_field")
.OrderBy(s.Count > 2 ? s[2] : "third_field")
.OrderBy(s.Count > 3 ? s[3] : "forth_field")
.OrderBy(s.Count > 4 ? s[4] : "fifth_field"))
.SelectPage(ProductVM.Map, query.page, query.pageSize, out count)
;
return result;
答案 0 :(得分:0)
使用创建整个Expression<Func>
表达式lambda的函数替换为OrderBy
参数创建OrderBy
的函数,然后将其传递给存储库。
在课程Me
中,
public static Expression<Func<IQueryable<TS>,IOrderedQueryable<TS>>> MyOrderByLambda<TS>(IQueryable<TS> _, string propertyName) {
//Create x=>x.PropName
var argx = Expression.Parameter(typeof(TS), "x");
var property = Expression.PropertyOrField(argx, propertyName);
var selector = Expression.Lambda(property, new ParameterExpression[] { argx });
//Create s=>s.OrderBy<TS, propertyInfo.Type>(x => x.@propertyName)
var args = Expression.Parameter(typeof(IQueryable<TS>), "s");
var genericOrderByMI = typeof(Queryable).GetMethods(BindingFlags.Static|BindingFlags.Public).First(mi => mi.Name == "OrderBy" && mi.GetParameters().Length == 2);
var orderByMI = genericOrderByMI.MakeGenericMethod(typeof(TS), property.Type);
var orderbybody = Expression.Call(orderByMI, args, selector);
var orderbyLambda = Expression.Lambda<Func<IQueryable<TS>, IOrderedQueryable<TS>>>(orderbybody, args);
return orderbyLambda;
}