在LINQ查询使用动态列名 [英] 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查询比较<$ C列表$ C> TVRawDataRecords 那些在尺寸
,并在没有匹配然后将它们添加到一个新的 DimensionIem的枚举
列表。这一切工作正常,但我需要在我的其中,
语句动态的 p.BrandVariant
替代品具有尺寸枚举值尺寸值是一样的 TVRawDataRecord
属性名称。这意味着我可以通过8个维度等的代码循环只是这几行。
I am trying to create a Linq query that compares a list of TVRawDataRecords
to those in an enum of Dimensions
and where there is no match then add them to a new DimensionIem
list. This all works fine but I need to substitute dynamically the p.BrandVariant
in my Where
statement with the dimensions enum value as the dimension value is the same as the TVRawDataRecord
property name. This would mean I can have just these few lines of code to loop through 8 dimensions etc.
有人能解释我是如何包括我Where语句维度?谢谢!
Can someone explain how I include the dimension in my Where statement? Thanks!
推荐答案
首先,这是真正做一个奇怪的事情。你首先应该想到的替代设计。有一对夫妇,现在来找我。
First and foremost this is really a bizarre thing to do. You should think of an alternate design first. There are a couple coming to me now.
反正你可以使用反射来实现你想达到什么目的。,以及几乎..
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
功能更通用的,但是这是一个不同的事情。在地图
函数(即一维枚举映射到 T
类型参数 TVRawDataRecord <财产/ code>类)传递,因为你需要知道属性的返回类型。
Strictly untested, uncompiled. But this should give an idea how it is done. You can make the GetPropertyValue
function more generic, but that's a different thing. The T
type argument in Map
function (that maps a dimension enum to property of TVRawDataRecord
class) is passed since you need to know the return type of the property.
我想说一个更好的替代设计,只是为了使用,如果其他逻辑返回正确类型的简单函数。因此,改变地图
函数如下:
I would say a better alternate design is just to make a simple function that uses if else logic to return the right type. So change Map
function to this:
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
。第二个例子难道不编译因为返回类型匹配犯规被返回的。如果所有属性都是同一类型的,那么你可以选择该类型。如果是这样真正的变量,那么你将有你的财产的第一对象,然后转换为 T
,但仍比反射更好!
The advantage is that even if in future you change the name of any of the variables, your code wouldn't break (unlike the reflection approach). But the catch here is to choose the return type T
. The second example wouldnt compile since return type doesnt match what is being returned. If all the properties are of the same type, then you can choose that type. If it's so really variable, then you will have to cast your property first to object and then to T
, but still better than reflection!!
An even better approach would be to specify attributes either to property or to enum.
最棒的一切,如果 BrandVariant
和创意
等都是自己的班,你可以让他们都在他们实现一个接口,这将有一个属性只读尺寸
,你可以访问该属性您的电视记录属性以获得正确的尺寸值!
And best of all if BrandVariant
and Creative
etc are classes of their own, you can make them all implement an interface which will have a property readonly Dimension
on them and you can access that property of your tv record properties to get the right dimension value!
这篇关于在LINQ查询使用动态列名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!