LINQ从多个属性的List(Of T)中选择Distinct对象不起作用

时间:2016-11-11 11:38:54

标签: vb.net linq

我的目标是根据三个propertiesCreatedBy, GrantedTo, PatientID选择对象。 以下是我在List(Of Access)

中提供的数据

enter image description here

所以从上面的例子中我应该只获得两个对象

1) CreatedBy:1, GrantedTo: 65, PatientID: 48
2) CreatedBy:1, GrantedTo: 66, PatientID: 48

但我得到 8

这是我的错误代码:

Dim distinctList As List(Of Access) = t.GroupBy(Function(p) New With {p.GrantedTo, p.PatientID, p.CreatedBy}).[Select](Function(g) g.First()).ToList()

我相信代码应该从每个唯一的对象组中选择第一个。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

你的逻辑有一个很大的缺陷:

  

所以从上面的例子中我应该只得到两个对象
  1)CreatedBy:1,GrantedTo:65,PatientID:48
  2)CreatedBy:1,GrantedTo:66,PatientID:48
  [...]
  我相信代码应该从每个唯一的对象组中选择第一个。

是的,您可以通过CreatedBy,GrantedTo和PatientID对您的数据进行分组 但是你得到的东西不能是(合理的)Access类型的对象,它不会是每个群组中的第一个。

为什么呢?因为当您想要从对象中选择所有数据时 - 以及AccessIDPermissionID等等 - 这些属性应具有哪些值?

在你的例子中1):
AccesID应该是238还是240? PermissionID应该是15还是18? ...
我想你明白了。

因此,您实际应该做的是仅选择分组数据,而不是Access个对象,而是选择匿名类型或定义类型。

匿名版:

Dim distinct = From acc In access
               Group By g = New With {Key .CreatedBy = acc.CreatedBy,
                                      Key .GrantedTo = acc.GrantedTo,
                                      Key .PatientID = acc.PatientID} Into Group

(此处必须使用Key关键字!)

现在,如果您想将这些不同的值传递给另一个对象/函数,您可以将它们作为单个参数传递:

For Each value In distinct
     foo.bar(value.g.CreatedBy, value.g.GrantedTo, value.g.PatientID)
Next

或者您创建一个自己的小类,其中只包含三个属性。 (由于时间不多,我把这一点留了下来,但应该是直截了当的。)

修改
尝试以下(盲目打字和未经测试):

Dim distinct = (From acc In access
               Group By g = New With {Key .CreatedBy = acc.CreatedBy,
                                      Key .GrantedTo = acc.GrantedTo,
                                      Key .PatientID = acc.PatientID} Into Group
               Select New Access With {.CreatedBy = g.CreatedBy, 
                                      .GrantedTo = g.GrantedTo, 
                                      .PateintID = g.PatientID}).ToList()

这应该为您提供List(Of Access) Access对象,并且只设置了三个属性。