2010-12-28 11 views
3

私は、プロパティと値に基づいてクエリに 'where'句を追加する関数を作成しようとしています。これは私の機能の非常に簡単なバージョンです。LinqとGenericsに関するヘルプ。クエリ内でのGetValueの使用

Private Function simplified(ByVal query As IQueryable(Of T), ByVal PValue As Long, ByVal p As PropertyInfo) As ObjectQuery(Of T) 

    query = query.Where(Function(c) DirectCast(p.GetValue(c, Nothing), Long) = PValue) 
    Dim t = query.ToList 'this line is only for testing, and here is the error raise 
    Return query 

End Function 

エラーメッセージがある:「System.ObjectのCompareObjectEqual(System.Objectの、System.Objectのブール)」メソッドLINQは、エンティティへの方法を認識しない、この方法は、ストア式に変換することができません。

aのように見えるのは、linqクエリ内でGetValueを使用できません。これを他の方法で達成することはできますか?

C#/ VBで回答を投稿してください。あなたはより快適に感じさせるものを選んだ。

おかげ

EDIT:私はまた、あなたはDirectCastを引き出し、代わりにラムダパラメータに反映しようとしたことがあり、同じ結果

Private Function simplified2(ByVal query As IQueryable(Of T)) 

    query = From q In query 
      Where q.GetType.GetProperty("Id").GetValue(q, Nothing).Equals(1) 
      Select q 
    Dim t = query.ToList 
    Return query 
End Function 

答えて

6

コードを式ツリーに変換する必要があります。

using System; 
using System.Linq; 
using System.Linq.Expressions; 
using System.Reflection; 

namespace WindowsFormsApplication1 
{ 
    static class Program 
    { 
     [STAThread] 
     static void Main() 
     { 
      using (var context = new NorthwindEntities()) 
      { 
       IQueryable<Customer> query = context.Customers; 
       query = Simplified<Customer>(query, "CustomerID", "ALFKI"); 
       var list = query.ToList(); 
      } 
     } 

     static IQueryable<T> Simplified<T>(IQueryable<T> query, string propertyName, string propertyValue) 
     { 
      PropertyInfo propertyInfo = typeof(T).GetProperty(propertyName); 
      return Simplified<T>(query, propertyInfo, propertyValue); 
     } 

     static IQueryable<T> Simplified<T>(IQueryable<T> query, PropertyInfo propertyInfo, string propertyValue) 
     { 
      ParameterExpression e = Expression.Parameter(typeof(T), "e"); 
      MemberExpression m = Expression.MakeMemberAccess(e, propertyInfo); 
      ConstantExpression c = Expression.Constant(propertyValue, propertyValue.GetType()); 
      BinaryExpression b = Expression.Equal(m, c); 

      Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(b, e); 
      return query.Where(lambda); 
     } 
    } 
} 
+0

テスト済みで働いています。完璧。ありがとう。 – Jonathan

+0

こんにちはTom。あなたは私にそのリンクを提供することができますか、なぜ表現木と一緒に働くのですが、lambdaを直接使っていないのかを簡単に説明できますか? – Ph0en1x

0

でこのコードを試してみましたか?このような何か:

query.Where(Function(c) _ 
    c.GetType().GetProperty(p, GetType("Int64")).GetValue(c, Nothing) = PValue) 

私はあなたにもラムダでこの種のものを行うことができますかどうか分からないが、それは試してみる価値です。

+0

私は同じエラーで、このいずれかを試してみました:クエリ= query.Where(。。機能(C)c.GetType()のGetProperty( "ID")GetValueメソッド(C、Nothing)で.Equals(p値)) '' '私は単純化するために存在する知っているプロパティー名をここで使用しました – Jonathan

関連する問題