使用反射来获取基于特定查询条件的值



我有一个与这里回答的问题略有不同的问题(使用反射从列表中检索值)

虽然这里批准的答案适用于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();
    }

我希望在最后的返回中更改">",这取决于传递到参数列表中的附加参数。我知道我可以做一个简单的切换,但有没有办法通过插入来改变条件?

您的代码实际上没有任何意义。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));

相关内容

  • 没有找到相关文章

最新更新