Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VB.NET LINQ到数据集(SQL';左外联接';可选)_Vb.net_Linq_Dataset - Fatal编程技术网

VB.NET LINQ到数据集(SQL';左外联接';可选)

VB.NET LINQ到数据集(SQL';左外联接';可选),vb.net,linq,dataset,Vb.net,Linq,Dataset,我想连接两个数据表,并根据结果创建第三个数据表。结果数据表应具有三列: 身份证 名字 出生年份 我的编译选项: 选项显式:On 选项严格:On 选项比较:二进制 选项推断:关闭 Dim dr As DataRow REM Dt1 Dim Dt1 As New DataTable Dt1.Columns.Add("ID", GetType(Integer)) Dt1.Columns.Add("Name", GetType(String)) dr = Dt1.NewRow dr("ID")

我想连接两个数据表,并根据结果创建第三个数据表。结果数据表应具有三列:

  • 身份证
  • 名字
  • 出生年份
我的编译选项:

  • 选项显式:On
  • 选项严格:On
  • 选项比较:二进制
  • 选项推断:关闭

    Dim dr As DataRow
    
    REM Dt1
    Dim Dt1 As New DataTable
    Dt1.Columns.Add("ID", GetType(Integer))
    Dt1.Columns.Add("Name", GetType(String))
    
    dr = Dt1.NewRow
    dr("ID") = 1
    dr("Name") = "Peter"
    Dt1.Rows.Add(dr)
    
    dr = Dt1.NewRow
    dr("ID") = 2
    dr("Name") = "Anna"
    Dt1.Rows.Add(dr)
    
    dr = Dt1.NewRow
    dr("ID") = 3
    dr("Name") = "John"
    Dt1.Rows.Add(dr)
    REM End Dt1
    
    REM Dt2
    Dim Dt2 As New DataTable
    Dt2.Columns.Add("ID", GetType(Integer))
    Dt2.Columns.Add("YearOfBirth", GetType(Integer))
    
    dr = Dt2.NewRow
    dr("ID") = 1
    dr("YearOfBirth") = 1970
    Dt2.Rows.Add(dr)
    
    dr = Dt2.NewRow
    dr("ID") = 2
    dr("YearOfBirth") = 1980
    Dt2.Rows.Add(dr)
    REM End Dt2
    
    Dim Dt3 As New DataTable
    
    Dim query As IEnumerable(Of DataRow) = From dr1 In Dt1.AsEnumerable()
                                           Group Join dr2 In Dt2.AsEnumerable()
                                           On dr1.Field(Of Integer)("ID") Equals dr2.Field(Of Integer)("ID")
                                           Into joined = Group
                                           From j In joined.DefaultIfEmpty()
                                           Select New With
                                               {
                                               .ID = dr1.Field(Of Integer)("ID"),
                                               .Name = dr1.Field(Of String)("Name"),
                                               .YearOfBirth = j.Field(Of Integer)("YearOfBirth")
                                               }
    
    
    Dt3 = query.CopyToDataTable
    
但我在编辑器(VS 2017)中得到了错误信息:

“错误BC36754:
“IEnumerable(匿名类型:ID为整数,Name为字符串,YearOfBirth为整数)”无法转换为“IEnumerable(Of DataRow)”,因为“匿名类型:ID为整数,Name为字符串,YearOfBirth为整数”不是从“DataRow”派生的,这是“接口IEnumerable(Of Out T)”中的“Out”泛型参数“T”所必需的。”
选择New
而不指定类名,因为查询结果将返回匿名类型(如
IEnumerable(属于匿名类型)
),并引发异常,因为
IEnumerable(属于匿名类型)
无法直接转换为
IEnumerable(属于数据行)

因此,您需要使用额外的
Select
方法将匿名类型转换为
DataRow
,该方法迭代
IEnumerable(匿名类型)
内容并返回
DataRow
(使用准备好的
DataTable
,其中包括列名作为结果集):

参考:


(C#version)

除非您的列表中包含您没有的
数据行,否则您不能调用
CopyToDataTable
。您需要自己创建
DataTable
,然后循环查询结果,为每个项目添加
DataRow
。谢谢,但我在查询中有一些错误。如果有人能为我编写正确的代码部分(Dim query…),这将对我非常有帮助。您的代码是可以的,但只是在条件下,数据表Dt1和Dt2都有ID为1、2和3的3行。如果数据表Dt2只有两行ID为1和2(没有ID 3),我会得到错误:“System.ArgumentNullException:'值不能为null。参数名称:row'”。我刚刚发现
出生年份
仅包含2行(对于ID 3,它设置为
无任何内容
)。与2个参数一起使用,检查
Nothing
,如果
DataRow
中有
Nothing
值,则返回默认整数值。如果使用
row(“出生年份”)=如果(r.YearOfBirth,0)
,则查询不正确。我在错误列表中看到此错误:错误BC33107:二进制“If”表达式中的第一个操作数必须是可空的或引用类型。如果我在代码
.YearOfBirth=j.Field(of Integer)(“YearOfBirth”)
对象的部分中使用,而不是
Integer
,则查询在形式上是可以的,但在启动后会出现错误:“System.ArgumentNullException:'值不能为null。参数名称:行”。如果我使用
Try…Catch
,我会看到错误出现在
Select New With
行上。好吧,我在错误的位置对
Nothing
进行了检查。如您所说,它应该放在
选择New With
中,并由确认。很抱歉有任何误解。现在查询非常好。你帮了我很多。非常感谢。
' joined DataTable columns
Dim JoinedDT As New DataTable
JoinedDT.Columns.Add("ID", GetType(Integer))
JoinedDT.Columns.Add("Name", GetType(String))
JoinedDT.Columns.Add("YearOfBirth", GetType(Integer))

' other stuff

Dim query As IEnumerable(Of DataRow) = (From dr1 In Dt1.AsEnumerable() _
                                       Group Join dr2 In Dt2.AsEnumerable() _
                                       On dr1.Field(Of Integer)("ID") Equals dr2.Field(Of Integer)("ID") _
                                       Into joined = Group _
                                       From j In joined.DefaultIfEmpty() _
                                       Select New With
                                       {
                                           .ID = dr1.Field(Of Integer)("ID"),
                                           .Name = dr1.Field(Of String)("Name"),
                                           .YearOfBirth = If(j IsNot Nothing, j.Field(Of Integer)("YearOfBirth"), 0)
                                       }).Select(Function(r)
                                           ' use `DataTable.NewRow` here
                                           Dim row As DataRow = JoinedDT.NewRow()
                                           row("ID") = r.ID
                                           row("Name") = r.Name
                                           row("YearOfBirth") = r.YearOfBirth
                                           Return row
                                       End Function)

Dt3 = query.CopyToDataTable()