使用反射根据特定查询条件获取值

时间:2014-04-09 12:31:04

标签: c# c#-4.0 generics reflection

我对此处回答的问题略有不同(Using reflection to retrieve a value from a list

虽然这里批准的答案适用于select,但我想扩展它以便我可以根据条件类型从查询中获取数据。目前,我改编的代码看起来像这样

 public static async Task<T> GetDataFromTable<T>(string paramName, string condition="")
    {
        var k = Activator.CreateInstance(typeof(T));
        var mn = typeof(T).GetProperty(paramName);
        var tc = typeof(T).GetProperty(condition);
        if (mn == null || !ftrackData.Online)
            return (T)k;
        var data = GetTableData<T>();
        if (!string.IsNullOrEmpty(paramName))
        {
            var retval = data.Select(t => mn.GetValue(t, null));
            return (T)retval;
        }
        else
            return (T)data.FirstOrDefault(t => mn.GetValue(t, null) > tc.GetType(t, null)).ToList();
    }

我希望得到&#34;&gt;&#34;在最终返回更改中,取决于传递到参数列表中的其他参数。我知道我可以在else之后做一个简单的切换,但有没有办法通过插入来改变条件?

1 个答案:

答案 0 :(得分:1)

你的代码没有任何意义。 Select扩展方法需要Func<T, TResult>,这意味着返回类型应为IEnumerable<TResult>,而您将其指定为T

在您的问题中,您希望在同一方法中执行SelectFirstOrDefault,但这是不可能的,因为结果类型会有所不同。

Select

public static async Task<IEnumerable<TResult>> SelectData<T, TResult>(
    string propertyName
)
{
    if(string.IsNullOrWhiteSpace(propertyName))
    {
        return Enumerable.Empty<TResult>();
    }

    var dataTask = GetTableData<T>();

    var tType = Expression.Parameter(typeof(T), "t");
    var property = Expression.Property(tType, propertyName);
    var selectExpression =
        Expression.Lambda<Func<T, TResult>>(property, tType)
                  .Compile();
    return (await dataTask).Select(selectExpression);
}

FirstOrDefault

public static async Task<T> FirstOrDefaultData<T>(
    string propertyName,
    string conditionName,
    Func<MemberExpression, MemberExpression, BinaryExpression> comparer
)
{
    if(string.IsNullOrWhiteSpace(propertyName) ||
       string.IsNullOrWhileSpace(conditionName) ||
       comparer == null
    {
        return default(T);
    }

    var dataTask = GetTableData<T>();

    var tType = Expression.Parameter(typeof(T), "t");
    var property = Expression.Property(tType, propertyName);
    var condition = Expression.Property(tType, conditionName);
    var binaryExpression =
        Expression.Lambda<Func<T, bool>>(comparer(property, condition), tType)
                  .Compile();
    return (await dataTask).FirstOrDefault(binaryExpression);
}

用法:

public class Foo
{
    public string Bar { get; set; }
    public bool Flag { get; set; }
}

var bars = SelectData<Foo, string>("Bar");
var foo = FirstOrDefaultData<Foo>("Bar",
                                  "Flag",
                                  (p, c) => Expression.GreaterThan(p, c));