ユーザーがドロップダウンリストから次の項目を選択するフォームがあります。
table_name
columnName_to_sort_by
columnName_to_search_in
ユーザはテキストボックスにSearch_text
を入力する
フォームは、多くのテーブルからデータを引き出すものとします。私は並べ替えを記述し、各テーブルのすべてのフィールドを検索しないようにしたい。これが私が表現木を使いたい理由です。私は動的にクエリを構築したい。
私は、ユーザーの入力に応じて、 select
、 where
およびorderby
メソッドの式ツリーを生成する汎用メソッドを記述したいと考えています。 System.Reflection
を使用して、照会されているType
を取得できます(すべてのテーブルが型です - LinqToSqlを使用しています)。
私は表現木の形成方法を知らない。
これまで私が持っていたことは次のとおりです。
private static List<T> GetSortedData<T>( string sortColumnName)
{
var type = typeof(T);
var property = type.GetProperty(sortColumnName);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);
MethodCallExpression resultExp = Expression.Call(typeof(Queryable), "OrderBy", new Type[] { type, property.PropertyType }, WHAT_SHOULD_BE_HERE, Expression.Quote(orderByExp));
return (List<T>)Expression.Lambda(resultExp).Compile().DynamicInvoke();
}
式ツリーを使ってselect
、 sort
、 orderby
をどのように実装select
か?
あなたが持っているものは近いです。 "WHAT_SHOULD_BE_HERE"と尋ねるところでは、OrderByの "source"パラメータを示すためにどのような式を使うのが好きですか?これは通常、拡張メソッドとして使用されるときにオペランドから暗示されます。必要なのは、IQueryableで動作するようにサンプルを変更することです。入力パラメータとして受け入れる必要があります。また、WHAT_SHOULD_BE_HEREプレースホルダを、以下に示すように "list.Expression"に置き換えてください。
private static IEnumerable<T> GetSortedData<T>(IQueryable<T> list, string sortColumnName)
{
var type = typeof(T);
var property = type.GetProperty(sortColumnName);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.Property(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);
MethodCallExpression resultExp = Expression.Call(typeof(Queryable), "OrderBy", new[] { type, property.PropertyType }, list.Expression, Expression.Quote(orderByExp));
return (IEnumerable<T>)Expression.Lambda(resultExp).Compile().DynamicInvoke();
}
私は次のコードでこれをテストしました:
static void Main(string[] args)
{
var list = new List<Person>(new[]
{
new Person { FirstName = "John" },
new Person { FirstName = "Jane" }
}).AsQueryable();
foreach (var o in GetSortedData(list, "FirstName"))
Console.WriteLine(o.FirstName);
}
public class Person
{
public string FirstName { get; set; }
}
どのプリントアウト:
Jane
John