【问题标题】:VB.NET GroupBy multiple number of propertiesVB.NET GroupBy 多个属性
【发布时间】:2020-10-02 07:26:02
【问题描述】:

目前,我有以下代码将“项目”分组,它是基于多个属性(prop1 和 prop2)的 List(Of CLass1)。

Dim matchedMethods  = items.GroupBy(Function(x) New With_
               {Key x.prop1, Key x.prop2, Key x.prop3}).ToList()

这适用于对已知数量的属性进行分组,但如果我希望它按“n 个属性”排序(prop1,然后是 prop2,然后是 prop3,然后是 propN...)。

【问题讨论】:

  • 你说 "grouping 已知数量的属性但是如果我想要它 sorted" - 用这个整个问题,你问的是分组还是排序?
  • 分组。具有相同 prop1=x、2=y、3=z 的项目应组合在一起,具有相同 prop1=x1、prop2=y2、prop3=z2 的项目应组合在一起,等等。如果这有意义的话
  • AFAIK 这就是它的工作原理:当 LINQ 为您进行分组时,您指定一个键,然后从中获得一系列 IGrouping,这有点像 Dictionary(Of keyType, List(Of inputValueType));每个 IGrouping 都有一个 Key,它本身就是一个分组值的列表。如果你有 5 个 Person 实例,三个叫 John,他是 27 岁,两个叫 Paul,年龄 38。你 GroupBy 名字和年龄你得到 2 个 IGrouping,一个有 John,27 的 Key 和 3 个 Person 对象(都是 John,27 ) 而另一个 IGrouping 的键是 Paul,38 并且是两个 Person 的枚举,这两个 Person 都是 Paul 和 38
  • 我试图让用户选择 GroupBy,所以不仅仅是“姓名”和“年龄”,还可以是“dob”或更多。我的问题(如果之前不清楚,请道歉)是我如何使用不同数量的分组。因此,与其像我在上面的代码中那样显式传递 3 个属性,不如我如何传递 n 个属性。用户可能只想按 prop1 或 prop1,2,3,4,5 或 prop3,2 等进行分组。

标签: vb.net linq


【解决方案1】:

您可以使用 System.Linq.Dynamic 库来实现这一点:它允许您在字符串中传递表达式(因此您可以动态构建字符串)。

我相信您在 SDL 中的代码将是:

Dim keySelector = "new(it.prop1, it.prop2, it.prop3)"
items.GroupBy(keySelector, "it").ToList()

(但我目前无法测试它)

为了改变它以不同的方式构建字符串:

Dim keySelector = "new("
If GroupByProp1CheckBox.Checked Then keySelector &= "it.prop1,"
If GroupByProp2CheckBox.Checked Then keySelector &= "it.prop2,"
...
keySelector = keySelector.TrimEnd(","c) & ")"

“it”是Dynamic.Linq中预定义的东西;相当于Function(x)中的x,即列表项

您需要通过 nuget 添加 System.Dynamic.Linq.Core。还有一个较旧的 System.Dynamic.Linq 库,根据我的经验,它更容易处理某些项目类型(例如 .net 框架窗口窗体)

【讨论】:

    【解决方案2】:

    所以我最终这样做了,基本上使用if语句根据propN的数量选择属性-->如果有一个则返回prop,否则什么都不返回。

    像我想要的那样工作(@Calius Jard),当我有时间时,将不得不在某个时候回到动态库(谢谢你的帮助)。 我对我的方法不太满意的唯一一点是密钥导出为 {v0=prop1, v1=prop2, vN=propN} 而不是列表或字典。所以,我最终使用了一些字符串操作来读取这些键。

       matchedRecords = items.GroupBy(Function(x) New With {Key .v0 = CallByName(x, prop(0).ToString, CallType.Get),
                                                          Key .v1 = If(prop.Count >= 2, CallByName(x, prop(1).ToString, CallType.Get), Nothing),  
                                                          Key .v2 = If(prop.Count >= 3, CallByName(x, prop(2).ToString, CallType.Get), Nothing),
                                                          Key .v3 = If(prop.Count >= 4, CallByName(x, prop(3).ToString, CallType.Get), Nothing),
                                                          Key .v4 = If(prop.Count >= 5, CallByName(x, prop(4).ToString, CallType.Get), Nothing),
                                                          Key .v5 = If(prop.Count >= 6, CallByName(x, prop(5).ToString, CallType.Get), Nothing)}).ToList
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      相关资源
      最近更新 更多