【发布时间】:2021-01-13 03:04:46
【问题描述】:
我需要将一个大表分解为一系列 2 列的表,以便为配置器引擎动态创建表规则。这段代码演示了这个问题:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Spike
{
class Program
{
static void Main(string[] args)
{
// The actual data I need to break down has ~20 properties of type string and decimal, over 18,000 rows
var data = new List<MyData>()
{
new MyData("one", "two", 3m, "four"),
new MyData("five", "six", 7m, "eight"),
new MyData("nine", "ten", 11m, "twelve"),
new MyData("thirteen", "fourteen", 15m, "sixteen"),
new MyData("one", "five", 9m, "thirteen"),
new MyData("two", "six", 10m, "fourteen"),
new MyData("three", "seven", 11m, "fifteen"),
new MyData("four", "eight", 12m, "sixteen")
};
// This shows the desired combinations of properties
// The actual data will have ~230 combinations
var properties = typeof(MyData).GetProperties(BindingFlags.Instance | BindingFlags.Public);
for (var i = 0; i < properties.Length - 1; i++)
{
for (var j = i + 1; j < properties.Length; j++)
{
Console.WriteLine($"{properties[i].Name} <=> {properties[j].Name}");
}
}
/* output:
P1 <=> P2
P1 <=> P3
P1 <=> P4
P2 <=> P3
P2 <=> P4
P3 <=> P4
*/
// This shows how I want one combination to appear
// The challenge seems to be the creation of a dynamic lambda in the Select method.
var items = data.Select(x => new { x.P2, x.P3 }).Distinct().ToList();
Console.WriteLine();
items.ForEach(x => Console.WriteLine($"{x.P2}, {x.P3}"));
/* output:
two, 3
six, 7
ten, 11
fourteen, 15
five, 9
six, 10
seven, 11
eight, 12
*/
Console.ReadKey();
}
}
public class MyData
{
public string P1 { get; set; }
public string P2 { get; set; }
public decimal P3 { get; set; }
public string P4 { get; set; }
public MyData(string p1, string p2, decimal p3, string p4)
{
P1 = p1;
P2 = p2;
P3 = p3;
P4 = p4;
}
}
}
我研究过 Linq、反射和表达式树,但似乎无法克服动态构建此表达式的障碍:
var items = data.Select(x => new { x.P2, x.P3 }).Distinct().ToList();
其中 x.P2 和 x.P3 是动态的。
This post 似乎正朝着正确的方向前进,但我没有得到结果。
建议?提前致谢!
【问题讨论】:
-
您的预期输出是什么?我不明白你在做什么。
-
不确定你真的需要
Expression,你可以用属性getter的CreateDelegate来做。但是你想做什么是?获得不同的属性组合?你考虑过{p1,p2}-{p2,p1}吗? -
嗨@Charlieface 和@Sweeper 是的,我所做的似乎没有意义,但在第三方配置引擎中是必需的。这就像尝试一次过滤两列的 Excel 电子表格 - 分别建立每列与所有其他列的关系。在这种情况下,{p1, p2} 意味着 {p2, p1}。我会看看
CreateDelegate。谢谢! -
如果你愿意,很高兴为你写点东西
标签: c# linq reflection expression-trees