我得到以下错误:
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: Product碰巧是使用Entity Framework从数据库表驱动的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;
}
编辑:这适用于微软的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;
发布于 2017-11-04 05:28:16
将为OrderBy
参数创建Expression<Func>
的函数替换为创建整个OrderBy
表达式lambda的函数,然后将其传递到存储库。
在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;
}
https://stackoverflow.com/questions/47103565
复制相似问题