gpt4 book ai didi

c# - 在 Linq 查询中使用动态列名

转载 作者:行者123 更新时间:2023-11-30 17:57:02 25 4
gpt4 key购买 nike

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 列表。这一切都很好,但我需要用维度枚举值动态替换 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功能更通用,但这是另一回事。 TMap 中输入参数函数(将维度枚举映射到 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 .第二个示例不会编译,因为返回类型与返回的内容不匹配。如果所有属性都属于同一类型,那么您可以选择该类型。如果它真的是可变的,那么你将不得不首先将你的属性转换为对象,然后再转换为 T。 ,但仍然比反射好!!

更好的方法是指定属性 to propertyto enum

最好的是 BrandVariantCreative etc 是它们自己的类,您可以让它们都实现一个接口(interface),该接口(interface)将具有只读属性 Dimension 在它们上,您可以访问电视记录属性的该属性以获得正确的维度值!

关于c# - 在 Linq 查询中使用动态列名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13519992/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com