以通用方式测试匿名类型的字段值

本文关键字:类型 字段 方式 测试 | 更新日期: 2023-09-27 18:25:35

我有以下linq到对象查询:

from tb ItemTable
where tb.id =555
select new
{
    field1=tb.field1,
    field2=tb.field2,
    ..
    ..
    ..
    fieldn=tb.fieldn
}

现在,碰巧所有这些字段的类型都是string,我想知道是否有任何字段不包含子字符串"ab"。但我想知道我是否可以避免写一个过滤器这样有:

where (tb.field1.Contains("ab") == false) && (tb.field2.Contains("ab") == false) ...

那么,我的问题是,在不使用上述方法的情况下,有什么方法可以做到这一点吗?

所有最好的

以通用方式测试匿名类型的字段值

由于无法迭代未知类型的字段,因此需要使用Reflection来迭代字段:

(from tb ItemTable
where tb.id =555
select new
{
    field1=tb.field1,
    field2=tb.field2,
    ..
    ..
    ..
    fieldn=tb.fieldn
})
.Where(item => !item.GetType().GetProperties()
    .Where(propertyInfo => propertyInfo.PropertyType == typeof(string))
    .Any(propertyInfo => ((string)propertyInfo.GetValue(item))
        .Contains("ab"));

请注意,反射非常慢因此,当在应用程序中多次重复执行此类操作时,您应该更喜欢通过代码生成进行过滤

由于反射的性能,以及所有未知类型都是相同的,我们可以获得一次属性,而不是每次迭代都获得它们:

var tableResults = (from tb ItemTable
    where tb.id =555
    select new
    {
        field1=tb.field1,
        field2=tb.field2,
        ..
        ..
        ..
        fieldn=tb.fieldn
    })
IEnumerable<PropertyInfo> propertyInfos =
    tableResults.FirstOrDefault()?.GetType().GetProperties()
        .Where(propertyInfo => propertyInfo.PropertyType == typeof(string));
tableResults = tableResults 
.Where(item => !propertyInfos
    .Any(propertyInfo => ((string)propertyInfo.GetValue(item))
        .Contains("ab")));

此外,如果可能的话,我会尽量避免未知类型,或者如果适合您的应用程序设计,可以考虑将字段存储在Enumerable中。