2

今日、文字列プロパティ名に基づいてラムダ式を返すメソッドがあります。つまり、「説明」を渡すと、d => d.Description のラムダが返されます。これはうまく機能しますが、ドット表記を含む文字列を指定してラムダ式を返す必要があります。つまり、「Customer.Name」を渡して、d => d.Customer.Name のラムダ式を取得したいと考えています。以下は、1レベルのラムダを返すメソッドを既に作成していますが、マルチレベルに変更する方法がわかりません。

protected dynamic CreateOrderByExpression(string sortColumn)
{
    var type = typeof (TEntity);
    Type entityType = null;
    if (type.IsInterface)
    {
        var propertyInfos = new List<PropertyInfo>();

        var considered = new List<Type>();
        var queue = new Queue<Type>();
        considered.Add(type);
        queue.Enqueue(type);
        while (queue.Count > 0)
        {
            var subType = queue.Dequeue();
            foreach (var subInterface in subType.GetInterfaces().Where(subInterface => !considered.Contains(subInterface)))
            {
                considered.Add(subInterface);
                queue.Enqueue(subInterface);
            }

            var typeProperties = subType.GetProperties(
                BindingFlags.FlattenHierarchy
                | BindingFlags.Public
                | BindingFlags.Instance);

            var newPropertyInfos = typeProperties
                .Where(x => !propertyInfos.Contains(x));

            propertyInfos.InsertRange(0, newPropertyInfos);

            if (propertyInfos.All(f => f.Name != sortColumn)) continue;

            entityType = subType;
            break;
        }
    }


    if (entityType == null)
    {
        return null;
    }

    var parameter = Expression.Parameter(typeof (TEntity));
    var memberExpression = Expression.Property(parameter, entityType, sortColumn);
    var lambdaExpression = Expression.Lambda(memberExpression, parameter);

    return lambdaExpression;
}
4

1 に答える 1

5

次のようなヘルパー メソッドを作成します (コードの下部で使用します)。

LambdaExpression GetLambdaExpression(Type type, IEnumerable<string> properties)
{
  Type t = type;
  ParameterExpression parameter = Expression.Parameter(t);
  Expression expression = parameter;

  for (int i = 0; i < properties.Count(); i++)
  {
    expression = Expression.Property(expression, t, properties.ElementAt(i));
    t = expression.Type;
  }

  var lambdaExpression = Expression.Lambda(expression, parameter);
  return lambdaExpression;
}

次のように使用します。

GetLambdaExpression(typeof(Outer), new[] { "InnerProperty", "MyProperty" });

次のクラスの場合:

class Outer
{
    public Inner InnerProperty { get; set; }
}

class Inner
{
    public int MyProperty { get; set; }
}

元のコードにもう少し適していた可能性があることはわかっていますが、ここから進むことができると思います(ドット付きの文字列を配列に変換するなど)。そして、再帰を使用して実行できたことは知っていますが、今日は頭痛がしました...

于 2013-09-19T14:03:55.387 に答える