2013-02-07 4 views
5

のための選択の方法を使用:、私は次の文に一致するように式ツリーを使用して動的クエリを作成しようとしています動的照会および式ツリー

var items = data.Where(i => i.CoverageType == 2).Select(i => i.LimitSelected); 

私はどこのメソッドを作成し、そこから結果を得ることができます。ただし、selectメソッドを作成することはできません。私はこのエラーを取得するコードを実行すると

var selectParm = Expression.Property(parm, "LimitSelected"); 
    var selectMethod = Expression.Call(
     typeof(Enumerable), 
     "Select", 
     new Type[]{typeof(BaseClassData), typeof(decimal)}, 
     whereMethod, 
     Expression.Lambda<Func<BaseClassData, decimal>>(selectParm, new ParameterExpression[]{ parm}) 

     ); 

var parm = Expression.Parameter(typeof(BaseClassData), "baseCoverage"); 

var queryData = data.AsQueryable(); 

var left = Expression.Property(parm, "CoverageType"); 
var right = Expression.Constant(2m); 
var e1 = Expression.Equal(left, right); 

var whereMethod = Expression.Call(
    typeof(Queryable), 
    "Where", 
    new Type[] { queryData.ElementType }, 
    queryData.Expression, 
    Expression.Lambda<Func<BaseClassData, bool>>(e1, new ParameterExpression[] { parm })); 

これは私がselectメソッドのために使用していますものです:メソッド私のはここ

がある

No generic method 'Select' on type 'System.Linq.Enumerable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic.

また、EnumerableをQueryableに変更しようとしましたが、同じエラーが発生します。

+3

「選択」と「場所」は** 2つの汎用パラメータを取る静的メソッドを作成しました。 – SLaks

+0

ParameterExpression配列の意味ですか?私は声明がコード化された通りにうまく動作するので尋ねる。 whereメソッドを使用してクエリを作成するだけであれば、すべて正常に動作します。それは、式ツリーにselectメソッドを追加しようとするときです。 – MarkSalow

+0

selectMethodの型配列にtypeof(BaseClassData)を追加しました。 – MarkSalow

答えて

-1

This might help with the error you describe above.

自分のクラスとC#/ LINQの作業に組み込まれたものだけで罰金、ここで、/しかし選択し、独自に作成する必要はありません:式を使用する

void Main() 
{ 
    List<testdata> data = new List<testdata>(); 
    Directory.GetFiles(@"C:\").ToList().ForEach(x=>data.Add(new testdata(){file=x,returnable=1})); 
    data.Where(x=>x.file.Contains("g")).Select(x=>x.file).Dump(); 
} 

class testdata 
{ 
    public string file {get; set;} 
    public string returnable {get; set;} 
} 
3

必要がありません。代わりに、代わりにExpression Treeを直接構築することもできます。

public static void Test(string[] args) { 
    using (var db = new DBContext()) { 
    //query 1 
    var query1 = db.PrizeTypes.Where(m => m.rewards == 1000).Select(t => t.name); 

    //query 2 which equal to query 1 
    Expression<Func<PrizeType, bool>> predicate1 = m => m.rewards == 1000; 
    Expression<Func<PrizeType, string>> selector1 = t => t.name; 
    var query2 = db.PrizeTypes.Where(predicate1).Select(selector1); 
    Console.WriteLine(predicate1); 
    Console.WriteLine(selector1); 
    Console.WriteLine(); 

    //query 3 which equal to query 1 and 2 
    Expression<Func<PrizeType, bool>> predicate2 = GetPredicateEqual<PrizeType>("rewards", (Int16)1000); 
    Expression<Func<PrizeType, string>> selector2 = GetSelector<PrizeType, string>("name"); 
    var query3 = db.PrizeTypes.Where(predicate2).Select(selector2); 
    Console.WriteLine(predicate2); 
    Console.WriteLine(selector2); 

    //as you can see, query 1 will equal query 2 equal query 3 
    } 
} 

public static Expression<Func<TEntity, bool>> GetPredicateEqual<TEntity>(string fieldName, object fieldValue) where TEntity : class { 
    ParameterExpression m = Expression.Parameter(typeof(TEntity), "t"); 
    var p = m.Type.GetProperty(fieldName); 
    BinaryExpression body = Expression.Equal(
    Expression.Property(m, fieldName), 
    Expression.Constant(fieldValue, p.PropertyType) 
); 
    return Expression.Lambda<Func<TEntity, bool>>(body, m); 
} 

public static Expression<Func<T, TReturn>> GetSelector<T, TReturn>(string fieldName) 
    where T : class 
    where TReturn : class { 
    var t = typeof(TReturn); 
    ParameterExpression p = Expression.Parameter(typeof(T), "t"); 
    var body = Expression.Property(p, fieldName); 
    return Expression.Lambda<Func<T, TReturn>>(body, new ParameterExpression[] { p }); 
} 
+0

Cheeeeeers、maaaaate ...私はこれを以前に見つけたかったと思う。私に多くの時間を節約できますか?私はそれを私のコードにコピーしました。 Ta! – Roman

関連する問題