c# - 使用 Linq 动态查询数据集

标签 c# linq dynamic-linq

我有一个要动态查询的数据集。如果我明确定义字段名称,此代码可以正常工作,但我不想这样做。我想使用字段名称的变量动态查询数据。我应该如何处理这个问题?

这个有效:

var dataField = "DemandStatusName";
var searchParam = form.GetValues("columns[" + j + "][search][value]").FirstOrDefault();

if(searchParam != "")
{
    dataSet = (from a in dataSet
               where a.DemandStatusName.Contains(searchParam)
               select a);
}

但这不是:

var dataField = "DemandStatusName";
var searchParam = form.GetValues("columns[" + j + "][search][value]").FirstOrDefault();

if(searchParam != "")
{
    dataSet = (from a in dataSet
               where dataField.Contains(searchParam)
               select a);
}

最佳答案

How should I be approaching this?

LINQ 的主要好处之一是您可以获得类型安全。通过动态查询,您本质上失去了这个好处。虽然不是真正的“动态”,但您可以通过编写包含您要查询的特定字段的扩展方法来保持这一优势:

public static IQueryable<MyTable> WhereContains(this IQueryable<MyTable> source, string field, string value)
{
  switch (field)
  {
    case nameof(MyTable.SomeField):
      return source.Where(a => a.SomeField.Contains(value));
    case nameof(MyTable.SomeOtherField):
      return source.Where(a => a.SomeOtherField.Contains(value));
    // ... etc
    default:
      throw new ArgumentOutOfRangeException($"Unexpected field {field}");
  }
}

这样,您的代码可以调用以下内容:

var dataField = "DemandStatusName";
var searchParam = form.GetValues("columns[" + j + "][search][value]").FirstOrDefault();

dataset.WhereContains(dataField, searchParam).OrderBy(a => a.Whatever)

也就是说,要从字面上回答您的问题,从技术上讲,您可以动态构建 LINQ 表达式。这可能看起来像这样,但请注意性能会很差,意外值可能会破坏它和/或打开一些安全漏洞,尤其是当它们来自用户输入时:

var table = Expression.Parameter(typeof(MyTable));
var property = Expression.PropertyOrField(table, dataField);
var param = Expression.Constant(searchParam);
var contains = Expression.Call(property, "Contains", Type.EmptyTypes, searchParam);
var expression = Expression.Lambda<Func<MyTable,bool>>(contains, table);

var result = dataset.Where(expression);

关于c# - 使用 Linq 动态查询数据集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54562570/

相关文章:

c# - 如何将字节数组转换为 UInt32 数组?

c# - Entity Framework 从 6.1.x 升级到 6.2.0 会中断某些查询,除非我启用 MARS

c# - 查询 XML 文件并创建文本文件

c# - .NET MongoDB C# 驱动程序不支持转换对象

c# - 如何使用 Dynamic Linq 命名字段?

c# - 将我的值类型转换为可空等效类型

c# - 如何让 MVVM Light Messenger 与 PCL 配合使用

c# - Newtonsoft Json.Net 序列化 JObject 不会忽略空值,即使设置正确

c# - 如何制作通用存储库?

c# - 在System.Linq.Dynamic.Select()中,如何简单的处理空对象引用?