【问题标题】:EF Core dynamically filter from listEF Core 从列表中动态过滤
【发布时间】:2021-04-16 20:28:49
【问题描述】:

我正在努力在前端表上创建一个通用动态过滤器。这个想法是每列都有一个过滤器,您可以在其中选择该列的值。列名必须是完全动态的和选定的值。我们正在使用 .NET 5 和 EF Core 5。

我想要的 SQL 查询是:


SELECT * 
FROM Users
WHERE externalId IN ('1234', '5678');

型号:


public class ColumnFilter
    {
        [Required]
        public string Name { get; set; } // column name
        public List<string> SelectedValues { get; set; } = new List<string>(); // values selected in this column
    }

public class User {
        public string Name { get; set; } 
        public string ExternalId { get; set; } 
}

简化代码:


//columnfilter really comes from API request
var columnFilter = new ColumnFilter{
Name = "ExternalId",
SelectedValues = new List<string>{ "1234", "5678" }
};

var queryable = _context.Users.AsNoTracking();

queryable = queryable.Where(f => columnFilter.SelectedValues.Contains(EF.Property<string>(f, columnFilter.Name)));

var values = await queryable.ToListAsync(); // 0 results

EF Core 生成此查询:

      SELECT *
      FROM [Users] AS [u]
      WHERE 0 = 1

如何让它动态工作?

【问题讨论】:

  • 我认为你应该看看Dynamic LINQ library,它应该可以为你解决问题。动态构建表达式
  • 该库对 sql 注入安全吗?
  • 您可以简单地动态构建 Expression,@Svyatoslav Danyliv 解决方案也应该是一个非常好的解决方案

标签: c# asp.net entity-framework .net-core entity-framework-core


【解决方案1】:

这是一个使用字符串值的示例:

var queryable = _context.Users.AsNoTracking();

queryable = queryable.FilterDynamic(columnFilter.Name, columnFilter.SelectedValues);

public static class QueryableExtensions
{
    public static IQueryable<T> FilterDynamic<T>(this IQueryable<T> query, string fieldName, ICollection<string> values)
    {
        var param = Expression.Parameter(typeof(T), "e");
        var prop = Expression.PropertyOrField(param, fieldName);
        var body = Expression.Call(typeof(Enumerable), "Contains", new[] {typeof(string)},
            Expression.Constant(values), prop);
        var predicate = Expression.Lambda<Func<T, bool>>(body, param);
        return query.Where(predicate);
    }
}

【讨论】:

    【解决方案2】:

    我的解决方案确实有效。我还涉及其他一些导致问题的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-26
      • 1970-01-01
      • 2022-01-08
      • 2019-05-21
      • 2022-10-23
      • 2017-09-22
      • 1970-01-01
      相关资源
      最近更新 更多