2017-11-03 1 views
0

変数の一般式のために推論することができない私は、次のエラーを取得しています:それはパラメータとして働く変数を作成するよう型引数は

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:

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; 
} 

で変数を使用している製品は、Entity Frameworkのを使用してデータベーステーブルからdrived POCOであることを起こります編集:これはMicrosoft Dynamic Linq拡張メソッドで動作しますが、非拡張メソッドの回答が必要です。ある時点でNetMageは、、long、およびintのようなオブジェクトから派生した変数に対して大きな効果を発揮したobjectデータ型を返したメソッドで応答しました。メソッドの戻り値の型としてobjectの代わりにdynamicを使用していますか?可能?

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

あなたの例とあなたの問題は、不適切にコンパイル時と実行時の型が混合されています。 'Me.GetOrder' - ' Product.GetType() 'への最初のパラメータを考えてみましょう。式の型は 'Type'なので、' TS'は 'Type'を意味し、' arg'の作成時に 'typeof(Type)'を実行しています。 – NetMage

+0

'Product'はどのようなタイプですか? – NetMage

+0

@NetMageプロダクトは、データベーステーブルから派生したPOCOです。 Entity FrameworkはPOCOをデータベースに接続します。クラス定義を追加します。 –

答えて

0

全体OrderBy表現ラムダを作成し、自分のリポジトリにそれを渡す機能をOrderByパラメータのExpression<Func>を作成するあなたの機能を交換してください。クラス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 => [email protected]) 
    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, new ParameterExpression[] { args }); 
    return orderbyLambda; 
} 
+0

Int64/longのようなデータ型がオブジェクトから派生していない場合はどうなりますか?(上記の質問に追加するInt64はSKUです)私はこれがStringデータ型のために働くと信じています。 –

+0

longをオブジェクトにすることはできないため、エラーが発生します。 – NetMage

+0

答えを更新して、OrderBy式を動的に作成し、タイプに関係なく、適切な答えを製品にコンパイル/実行しましたが、別のライブラリに渡したい場合は動作しません。 – NetMage