通过在where条件下执行字符串子句来筛选匿名对象列表

本文关键字:筛选 列表 对象 子句 字符串 where 条件下 执行 | 更新日期: 2023-09-27 17:59:27

DOTNETFIDDLE

我创建了一个匿名对象列表,如下所示。。。。。

List < Object > _dynamicObjectList = new List < Object > ();
for (int i = 0; i < 5; i++) {
    _dynamicObjectList.Add(new {
        ID = i, Name = "stu" + i, Address = "address234324" + i, DateField = DateTime.Now.AddDays(i)
    });
}

现在我需要创建字符串查询。下面给出了我的字符串查询。。

string searchStr ="it.ID= 1 || it.ID= 2 || it.Name= "stu1" || it.Name= "stu2"";

在最后一步中,我将用上面的字符串过滤我的列表。。。

var returnList= _dynamicObjectList.GetFilteredData(searchStr );

下面给出了执行动态对象的方法。。。

public static IQueryable GetFilteredData < T > (this IEnumerable < T > source, string searchCriteria) {
    if (!string.IsNullOrEmpty(searchCriteria)) {
        IList < T > returnList = new List < T > ();
        returnList = source.AsQueryable().Where(searchCriteria).ToList();
        return returnList.AsQueryable();
    } else {
        return source.AsQueryable();
    }
}

在执行过程中,系统提供错误

类型"Object"中不存在属性或字段"ID"

通过在where条件下执行字符串子句来筛选匿名对象列表

<T>Object,因为您传入的是List<Object>,而对象上没有您要查找的属性。

如果您的_dynamicObjectList被声明为这些匿名类型的列表,那么查询可以很好地执行,例如,如果您将_dynamicObjectList声明为:

var _dynamicObjectList = new[] {
            new {ID = 0, Name = "stu" + 0, Address = "address234324" + 0, DateField = DateTime.Now.AddDays(0)},
            new {ID = 1, Name = "stu" + 1, Address = "address234324" + 1, DateField = DateTime.Now.AddDays(1)},
            new {ID = 2, Name = "stu" + 2, Address = "address234324" + 2, DateField = DateTime.Now.AddDays(2)},
            new {ID = 3, Name = "stu" + 3, Address = "address234324" + 3, DateField = DateTime.Now.AddDays(3)},
            new {ID = 4, Name = "stu" + 4, Address = "address234324" + 4, DateField = DateTime.Now.AddDays(4)},
        }.ToList();

更多信息:匿名类的通用列表

如果可能的话,我认为你最好的选择是避免使用匿名类型,只创建一个类来保存你的数据。

初始化列表的一种简单方法是使用Enumerable.Range和匿名类型:

var list = Enumerable.Range(0,5).Select(i => new {
    ID = i, 
    Name = "stu" + i, 
    Address = "address234324" + i, 
    DateField = DateTime.Now.AddDays(i)
});

不管你初始化它的方式如何,我看到你的GetFilteredData方法有两个主要问题:

  1. 不能将匿名类型传递给泛型函数。您需要将其强制转换为IEnumeration<object>或使用dynamic类型,这完全违背了匿名类型的目的
  2. 您需要将searchCriteria中的文本解析为某种类型的条件列表,然后才能将其应用于您的集合。根据允许的语法,它可能是一个简单的任务,也可能不是那么简单。当您得到解析器时,您将需要编写一个扩展.Where方法,该方法接受string作为标准

如果你为你的收藏定义一个常规类型,并明确过滤标准,你会让你的生活更轻松。根据你的例子,它们可以是两个简单的列表-一个用于ID,另一个用于名称。然后,您可以将字符串解析为这两个集合,然后使用这些集合来过滤原始列表。