【问题标题】:LINQ Dynamic ListLINQ 动态列表
【发布时间】:2016-08-09 17:00:13
【问题描述】:

我有课:

Public Class Data

    Public Property ColumnList As List(Of Column)
    Public Property RowList As List(Of Row)
End Class

Public Class Row

    Public Property CellList As List(Of Cell)
End Class

Public Class Column

    Public Property name As String
End Class

Public Class Cell

    Public Property value As Object
    Public Property col As Column
End Class

然后我想检查列名列表是否是数据的主键(如 SQL),例如

ColumnFieldNames = {"FieldA", "FieldB"}

ColumnList 包含 3 个名为 FieldAFieldBFieldCColumnRowList 包含 3 个 CellLists,每个都填充了 FieldAFieldBFieldC 的值以及对 Column 的引用。

Data.ColumnList(0).name = "FieldA" 
Data.ColumnList(1).name = "FieldB"
data.RowList(0).CellList(0).value = 1
data.RowList(0).CellList(0).column = ColumnList(0)
data.RowList(0).CellList(1).value = 2
data.RowList(0).CellList(1).column = ColumnList(1)
data.RowList(1).CellList(0).value = 34
data.RowList(1).CellList(0).column = ColumnList(0)
data.RowList(1).CellList(1).value = 2
data.RowList(1).CellList(1).column = ColumnList(1)

等等

我想要某种group by ... having count(*) > 1select count(1) - 声明所以如果我选择FieldB 作为ColumnFieldNames 它会返回一些东西,因为有不止一行包含CellList.value = 2。如果我选择 {"FieldA", "FieldB"} 作为ColumnFieldNames,它不会返回任何内容。

【问题讨论】:

    标签: vb.net linq list


    【解决方案1】:

    我认为它的主要目标是检查一组字段是否可以代表数据结构上的主键。换句话说,如果一组字段可以唯一标识一行。

    正如 FloatingKiwi 指出的那样,您最好使用 DataTable 类。它为您提供了许多方便的实用程序来存储和处理您的数据。这个简单的代码可能会回答您的问题:

    Private Function IsPK_DataTable(data As DataTable, ParamArray fields As String()) As Boolean
        Return New DataView(data).ToTable(True, fields).Rows.Count = data.Rows.Count
    End Function
    

    这里的数据首先用DataView 对象包装,它允许我们只从数据表中选取选定的列(使用ToTable(..., fields)),并且只选取这些选定列唯一的行(通过传递True作为ToTable()的第一个参数)。现在,如果结果行数与初始行数匹配,则传递的字段集可能是我们数据的主键。

    完整的演示代码可以在这里找到:https://dotnetfiddle.net/6fhMgv


    如果您仍然倾向于使用自定义数据结构表示,则相应的主键检查函数可能如下所示:

    Private Function IsPK_CustomData(data As Data, ParamArray fields As String()) As Boolean
        Dim keyValues = data.RowList _
            .[Select](Function(r) r.CellList.Where(Function(c) fields.Contains(c.col.name)) _
            .[Select](Function(c) c.value).ToArray()).ToArray()
        For i As Integer = 1 To keyValues.Length - 1
            For j As Integer = i - 1 To 0 Step -1
                If keyValues(i).SequenceEqual(keyValues(j)) Then
                    Return False
                End If
            Next
        Next
        Return True
    End Function
    

    完整演示:https://dotnetfiddle.net/RDl5Nl

    【讨论】:

      【解决方案2】:

      您似乎在这里重新发明轮子。 DataTable 类已经可以处理您的类结构,并支持类似 sql 的过滤器表达式。对于分组,请尝试查看以下帖子: Efficient DataTable Group By

      【讨论】:

      • 旧轮子太圆了。
      猜你喜欢
      • 1970-01-01
      • 2011-04-10
      • 2014-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-25
      相关资源
      最近更新 更多