请使用VB.Net解答!第一个问题:Linq语句中Group join与DefaultIfEmpty的结合,第二个问题:将自定义比较器作为参数时,没反应
望諸公 2020-08-06 08:18:43 Public Function Test2() As Boolean
Dim S(0) As String
'测试数据
Dim DT1 As New DataTable
DT1.TableName = "表1"
Dim DC1(0) As DataColumn
DC1(0) = New DataColumn
DC1(0).DataType = System.Type.GetType("System.String")
DC1(0).ColumnName = "主键1"
DT1.Columns.Add(DC1(0))
DT1.PrimaryKey = DC1
DC1(0) = New DataColumn
DC1(0).DataType = System.Type.GetType("System.String")
DC1(0).ColumnName = "列1" '取值于表:DT2 的主键
DT1.Columns.Add(DC1(0))
MsgBox(DT1.Columns.Count)
Dim DR1 As DataRow
Dim J As Integer
For J = 0 To 10 Step 1
DR1 = DT1.NewRow
DR1.BeginEdit()
DR1.Item("主键1") = "M1" & J
If J <= 5 Then DR1.Item("列1") = "F" & J '6个相等值,5个空值
DR1.EndEdit()
DT1.Rows.Add(DR1)
DR1.AcceptChanges()
Next J
MsgBox(DT1.Rows.Count)
Dim DT2 As New DataTable
DT2.TableName = "表2"
DC1(0) = New DataColumn
DC1(0).DataType = System.Type.GetType("System.String")
DC1(0).ColumnName = "主键2"
DT2.Columns.Add(DC1(0))
DT2.PrimaryKey = DC1
DC1(0) = New DataColumn
DC1(0).DataType = System.Type.GetType("System.String")
DC1(0).ColumnName = "显示列2"
DT2.Columns.Add(DC1(0))
MsgBox(DT2.Columns.Count)
For J = 0 To 10 Step 1
DR1 = DT2.NewRow
DR1.BeginEdit()
DR1.Item("主键2") = "F" & J
DR1.Item("显示列2") = "S" & J
DR1.EndEdit()
DT2.Rows.Add(DR1)
DR1.AcceptChanges()
Next J
MsgBox(DT2.Rows.Count)
'相等行测试
Dim Linq2 = From row1 As DataRow In DT1 Join row2 As DataRow In DT2 On row1.Item("列1") Equals row2.Item("主键2") Select row1, Show1 = row2.Item("显示列2")
For J = 0 To Linq2.Count - 1 Step 1
S(0) &= Chr(13) & Linq2(J).Show1
Next J
MsgBox(S(0)) '获得6行,正常
'第一个问题:Group1.Item("显示列2"),引发错误,原因是 Group1 未将对象引用设置到对象的实例。
Dim Linq1 = From row1 As DataRow In DT1 Group Join row2 As DataRow In DT2 On row1.Item("列1") Equals row2.Item("主键2") Into Group
From Group1 In Group.DefaultIfEmpty()
Select New Struct1 With {.DataRow1 = row1, .Count1 = 1, .FldName0 = "显示列2", .FldValue0 = IIf(Group1 Is Nothing, DBNull.Value, Group1.Item("显示列2")), .FldType0 = "System.String"}
MsgBox("左外联接行数 = " & Linq1.Count)
'自定义比较器
Dim ICompareStruct1Class As New ICompareStruct1
MsgBox(ICompareStruct1Class.Compare(Linq1(0), Linq1(1))) '测试正常
第二个问题:自定义比较器作为 OrderByDescending 或 OrderBy 的参数时,没有调动 Compare方法,没有排序
Linq1.OrderByDescending(Function(X) X, ICompareStruct1Class)
For J = 0 To Linq1.Count - 1 Step 1
S(0) &= Chr(13) & Linq1(J).DataRow1.Item(0)
Next J
MsgBox(S(0))
DT1.Dispose()
DT2.Dispose()
End Function
'自定义结构
Public Structure Struct1
Public DataRow1 As DataRow
Public Count1 As Integer '标记实际使用的 从1开始,最大是10的 参数个数
'字段值
Public FldValue0 As Object
Public FldValue1 As Object
Public FldValue2 As Object
Public FldValue3 As Object
Public FldValue4 As Object
Public FldValue5 As Object
Public FldValue6 As Object
Public FldValue7 As Object
Public FldValue8 As Object
Public FldValue9 As Object
'字段名称
Public FldName0 As String
Public FldName1 As String
Public FldName2 As String
Public FldName3 As String
Public FldName4 As String
Public FldName5 As String
Public FldName6 As String
Public FldName7 As String
Public FldName8 As String
Public FldName9 As String
'字段.数据类型
Public FldType0 As String
Public FldType1 As String
Public FldType2 As String
Public FldType3 As String
Public FldType4 As String
Public FldType5 As String
Public FldType6 As String
Public FldType7 As String
Public FldType8 As String
Public FldType9 As String
End Structure
'自定义比较器
Public Class ICompareStruct1
Implements IComparer(Of Struct1)
Implements IDisposable
'自定义结构:Struct1 的排序比较器
Private CompareValue1 As Integer
Public Sub New()
End Sub
Protected disposed As Boolean = False
Sub Dispose() Implements IDisposable.Dispose
Me.Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overridable Sub Dispose(disposing As Boolean)
If Not Me.disposed Then
If disposing = True Then
End If
End If
Me.disposed = True
End Sub
Public Function Compare(X As Struct1, Y As Struct1) As Integer Implements IComparer(Of Struct1).Compare
Dim J As Integer
For J = 0 To X.Count1 - 1 Step 1
Select Case J
Case 0
CompareValue1 = CompareDetail(X.FldValue0, Y.FldValue0, X.FldType0)
Case 1
CompareValue1 = CompareDetail(X.FldValue1, Y.FldValue1, X.FldType1)
Case 2
CompareValue1 = CompareDetail(X.FldValue2, Y.FldValue2, X.FldType2)
Case 3
CompareValue1 = CompareDetail(X.FldValue3, Y.FldValue3, X.FldType3)
Case 4
CompareValue1 = CompareDetail(X.FldValue4, Y.FldValue4, X.FldType4)
Case 5
CompareValue1 = CompareDetail(X.FldValue5, Y.FldValue5, X.FldType5)
Case 6
CompareValue1 = CompareDetail(X.FldValue6, Y.FldValue6, X.FldType6)
Case 7
CompareValue1 = CompareDetail(X.FldValue7, Y.FldValue7, X.FldType7)
Case 8
CompareValue1 = CompareDetail(X.FldValue8, Y.FldValue8, X.FldType8)
Case 9
CompareValue1 = CompareDetail(X.FldValue9, Y.FldValue9, X.FldType9)
End Select
If CompareValue1 <> 0 Then Exit For
Next J
MsgBox(J & ", X.首值 = " & X.DataRow1.Item(0) & ",Y.首值 = " & Y.DataRow1.Item(0) & ", X值 = " & X.FldValue0 & ", Y值 = " & Y.FldValue0 & ", 数据类型 = " & X.FldType0 & ", 比较结果 = " & CompareValue1.ToString)
Return CompareValue1
End Function
End Class