Linq连接选择所有列和CopyToDataTable

时间:2017-10-04 19:26:40

标签: vb.net linq join datatable

TABLE SCHEMA我无法在linq中解析数据集中的查询;我必须在两个数据表之间进行简单的左连接,但我事先并不知道数据表B中的确切列数(A,B,C ......?),所以我想选择所有列;我找到了以下链接

select-all-columns-after-join-in-linq

select-all-columns-for-all-tables-in-join-linq-join

        Dim Query = From A In TableA _
                    Join B In TableB _
                    On A("COD") Equals B("COD") _
                    Select New With {A, B}
        Dim TableC As DataTable = Query.CopyToDataTable()

我也尝试了

Select New With {.DAT = A.ItemArray.Concat(P.ItemArray).ToArray()}).ToList

还有更多,但我没有将查询结果带到新数据表;我收到了类型转换错误,或者我不明白如何将两个单独的表中提供的查询结果合并到一个数据表中。

1 个答案:

答案 0 :(得分:0)

创建一些扩展方法并使用Reflection会做你想要的,虽然这可能不是解决你的问题的理想方法(通常,反射永远不会)。

Public Module SomeExt
<System.Runtime.CompilerServices.Extension()>
Public Function GetTypedValue(Of TProp)(ByVal p As PropertyInfo, obj As Object) As TProp
    Return DirectCast(p.GetValue(obj), TProp)
End Function

<System.Runtime.CompilerServices.Extension()>
Public Function FlattenToDataTable(Of T)(src As IEnumerable(Of T)) As DataTable
    Dim ans = New DataTable()

    Dim srcdtpis = GetType(T).GetProperties().Cast(Of PropertyInfo)().ToList()
    For Each aDT As DataTable In srcdtpis.Select(Function(pi) pi.GetTypedValue(Of DataRow)(src.First()).Table)
        For Each col In aDT.Columns.Cast(Of DataColumn)()
            ans.Columns.Add(col.ColumnName, col.DataType)
        Next
    Next

    For Each drs In src
        Dim newDR = ans.NewRow
        For Each aDR In srcdtpis.Select(Function(pi) pi.GetTypedValue(Of DataRow)(drs))
            For Each colname In aDR.Table.Columns.Cast(Of DataColumn)().Select(Function(dc) dc.ColumnName)
                newDR(colname) = aDR(colname)
            Next
        Next
        ans.Rows.Add(newDR)
    Next

    Return ans
End Function
End Module

您可以按如下方式使用它:

Dim Query = From A In TableA.AsEnumerable() _
                Join B In TableB.AsEnumerable() _
                On A("COD") Equals B("COD") _
                Select New With {A, B}
Dim TableC As DataTable = Query.FlattenToDataTable()

请注意,重复的列名称将设置为最后DataTable的值。