C# 使用字符串参数来定义对象列表中要过滤的属性

and*_*lin 3 c# linq .net-core

我想使用 filterType 参数来定义 Stock 对象上要过滤的属性。

[HttpGet("{searchText}/{filterType}")] 
public async Task<ActionResult<List<Stock>>> Get(string searchText, string filterType)
 {
    List<Stock> v = await this._context.StockView.Where(w => w.[filterType] == searchText).ToListAsync();

    return this.Ok(v);
 }
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点,我可以使用字符串参数来定义要限制的对象的属性?

phu*_*uzi 5

您可以使用表达式树动态构建 Linq where 子句来过滤动态属性。

我知道这可能需要消化很多东西,但是,就这样吧。将 StockItem 替换为 StockView DbSet 的类型

[HttpGet("{searchText}/{filterType}")] 
public async Task<ActionResult<List<Stock>>> Get(string searchText, string filterType)
{
    var queryableStockView = this._context.StockView;

    // w =>
    var param = Expression.Parameter(typeof(StockItem), "w");

    var propertyInfo = typeof(StockItem).GetProperty(filterType);
    if (propertyInfo == null)
        throw new Exception($@"Property ""{property}"" was not found");

    // w.[filterType]
    var left = Expression.Property(param, propertyInfo);

    // searchText
    var right = Expression.Constant(searchText, typeof(string));

    // w.[filterType] == searchText
    var expression = Expression.Equal(left, right);
    
    // Bring it all together
    // Where(w => (w.[filterType] == searchText))
    var whereExpression = Expression.Call(
        typeof(Queryable),
        nameof(System.Linq.Enumerable.Where),
        new Type[] { queryableStockView.ElementType },
        queryableStockView.Expression,
        Expression.Lambda<Func<StockItem, bool>>(expression, new ParameterExpression[] { param })
    );

    // Run query against the database                                     
    var filteredItems = queryableStockView.Provider.CreateQuery<StockItem>(whereExpression);

    var v = await filteredItems.ToListAsync();

    return this.Ok(v);
 }
Run Code Online (Sandbox Code Playgroud)

动态生成的 Linq 表达式应该可以毫无问题地转换为 SQL。