[英]Using Dynamic Column Names in a Linq Query
foreach (Dimension dimensions in Enum.GetValues(typeof(Dimension)))
{
var r = new ReferenceTable(dimensions).referenceItems;
List<TVRawDataRecord> qry = TVRawDataList.Where(p => !r.Any(d => d.Value == p.BrandVariant))
.ToList();
DimensionItem di = new DimensionItem(qry, dimensions);
newDimensions.Add(di);
}
我想创建一个LINQ查询比较列表TVRawDataRecords
中的枚举的Dimensions
和那里是没有匹配然后将它们添加到一个新的DimensionIem
列表。 这一切都运行正常但我需要动态p.BrandVariant
我的Where
语句中的p.BrandVariant
和维度枚举值,因为维度值与TVRawDataRecord
属性名称相同。 这意味着我可以只用这几行代码来循环遍历8个维度等。
有人可以解释我如何在Where语句中包含维度吗? 谢谢!
首先,这真的是一件奇怪的事情。 您应该首先考虑替代设计。 现在有一对夫妇来找我。
无论如何,你可以使用反射来实现你想要实现的目标。 ,差不多......
foreach (Dimension dimension in Enum.GetValues(typeof(Dimension)))
{
var r = new ReferenceTable(dimension).referenceItems;
var qry = TVRawDataList.Where(p => !r.Any(d => IsAMatch(p, dimension, d.Value)))
.ToList();
DimensionItem di = new DimensionItem(qry, dimension);
newDimensions.Add(di);
}
bool IsAMatch<T>(TVRawDataRecord obj, Dimension dimension, T valueToMatch)
{
return valueToMatch == dimension.MapToTvRecordProperty<T>(obj);
}
T MapToTvRecordProperty<T>(this Dimension dimension, TVRawDataRecord obj)
{
return obj.GetPropertyValue<T>(dimension.ToString());
}
T GetPropertyValue<T>(this TVRawDataRecord obj, string propertyName)
{
var property = typeof(TVRawDataRecord).GetProperty(propertyName);
if (property == null)
return null; //or throw whatever
return (T)property.GetValue(obj, null);
}
严格未经测试,未编译。 但这应该让人知道它是如何完成的。 您可以使GetPropertyValue
函数更通用,但这是另一回事。 传递Map
函数中的T
类型参数(将维度枚举映射到TVRawDataRecord
类的属性),因为您需要知道属性的返回类型。
我想说一个更好的替代设计只是创建一个简单的函数,使用if else逻辑来返回正确的类型 。 所以将Map
功能更改为:
T MapToTvRecordProperty<T>(this Dimension dimension, TVRawDataRecord obj)
{
switch (dimension)
{
case Dimension.BrandVariant:
return obj.BrandVariant;
case Dimension.Creative:
return obj.Creative;
.....
default:
throw;
}
}
优点是,即使将来更改任何变量的名称,您的代码也不会中断(与反射方法不同)。 但这里的问题是选择返回类型T
第二个例子不会编译,因为返回类型与返回的内容不匹配。 如果所有属性属于同一类型,则可以选择该类型。 如果它真的是变量,那么你必须首先将你的属性转换为object然后转换为T
,但仍然比反射更好!
最重要的是,如果BrandVariant
和Creative
等都是他们自己的类,你可以让他们都实现一个接口,在它们上面只有一个属性readonly Dimension
,你可以访问你的tv记录属性的属性,以获得正确的维度值!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.