以通用方式测试匿名类型的字段值
本文关键字:类型 字段 方式 测试 | 更新日期: 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
中。