Linq联接选择所有列和CopyToDataTable [英] Linq join select all columns and CopyToDataTable

查看:231
本文介绍了Linq联接选择所有列和CopyToDataTable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

表架构我在解决linq中对数据集的查询时遇到了麻烦;我必须在两个数据表之间做一个简单的左连接,但我事先不知道数据表B中的确切列数(A,B,C ...?),所以我想选择所有列.我找到了以下链接

TABLE SCHEMA I'm having trouble solving a query in linq to dataset; I have to make a simple left join between two datatable but I do not know in advance the exact number of columns in the datatable B (A, B, C ...?) so I wanted to select all the columns; I found the following link

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

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

and many more but i failed to bring the query result to a new datatable; I received type conversion errors or i did not understand how to bring the query result provided in two separate tables into one datatable.

推荐答案

创建某些扩展方法并使用Reflection将完成您想要的事情,尽管这可能不是解决问题的理想方法(通常,Reflection从来都不是).

Creating some extension methods and using Reflection will do what you want, though this may not be the ideal way to solve your issue (generally, Reflection never is).

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

您将按以下方式使用它:

You would use it as follows:

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的值.

Note that duplicate column names will be set to the last DataTable's value.

这篇关于Linq联接选择所有列和CopyToDataTable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆