首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >不能为泛化表达式变量推断类型参数

不能为泛化表达式变量推断类型参数
EN

Stack Overflow用户
提问于 2017-11-04 03:56:22
回答 1查看 67关注 0票数 0

我得到以下错误:

代码语言:javascript
复制
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()的参数?这段代码只是一个测试。我需要将变量发送到外部存储库。

代码语言:javascript
复制
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:

代码语言:javascript
复制
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中使用变量

代码语言:javascript
复制
// 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等对象派生的变量非常有效,但longint仍然失败。也许使用dynamic而不是object作为方法返回类型是可行的?有可能吗?

代码语言:javascript
复制
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;
EN

回答 1

Stack Overflow用户

发布于 2017-11-04 05:28:16

将为OrderBy参数创建Expression<Func>的函数替换为创建整个OrderBy表达式lambda的函数,然后将其传递到存储库。

Me类中,

代码语言:javascript
复制
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;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47103565

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档