【问题标题】:c# use string parameter to define what property to filter by in List of objectsc#使用字符串参数定义在对象列表中过滤的属性
【发布时间】:2019-12-27 16:17:28
【问题描述】:

我想使用 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);
 }

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

【问题讨论】:

  • 你试过反射吗?

标签: c# linq .net-core


【解决方案1】:

您可以使用表达式树来动态构建 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");

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

    // 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);
 }

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

【讨论】:

    【解决方案2】:

    要做你想做的事,你需要编写一堆映射代码。(超出范围,你需要展示你尝试过的东西)

    执行原始 sql 会更容易,因为您可以动态设置字段。

    或者,您可以设置您的数据以支持您的搜索...见下文。

    [HttpGet("{searchText}/{filterType}")] 
    public async Task<ActionResult<List<Stock>>> Get(string searchText, string filterType)
     {
        var v = await this._context.StockView
                  .Where(x => x.Type == filterType 
                           && x.SearchField == searchText).TolistAsync();
    
        return this.Ok(v);
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-11
      • 2020-07-01
      • 1970-01-01
      • 2011-12-01
      • 1970-01-01
      相关资源
      最近更新 更多