使用子查询中的动态字段将双表exists查询从SQL转换为Linq
我正在尝试查询旧的Access数据库表,并将它们与SQL Server表进行比较。 它们通常没有主键,或者它们有额外的字段,这些字段在九十年代有一些用途,等等,或者新表有新字段,等等 我需要根据运行时指定的一组字段查找一个表中的记录,而不是另一个表中的记录 所以,当我比较不同表中的数据时,我总是在SQL中执行这种查询:使用子查询中的动态字段将双表exists查询从SQL转换为Linq,sql,vb.net,linq,subquery,exists,Sql,Vb.net,Linq,Subquery,Exists,我正在尝试查询旧的Access数据库表,并将它们与SQL Server表进行比较。 它们通常没有主键,或者它们有额外的字段,这些字段在九十年代有一些用途,等等,或者新表有新字段,等等 我需要根据运行时指定的一组字段查找一个表中的记录,而不是另一个表中的记录 所以,当我比较不同表中的数据时,我总是在SQL中执行这种查询: dim fields_i_care_about as string = "field1, field2, field3" 'This kind of thing gets se
dim fields_i_care_about as string = "field1, field2, field3"
'This kind of thing gets set by a caller, can be any number of fields, depends on the
'table
dim s as string= ""
dim flds = fields_i_care_about.split(",")
for i as integer = 0 to ubound(flds)
if s > "" then s += " AND "
s += " dysfunctional_database_table." & flds(i) & "=current_database_table." & flds(i)
next
s = "SELECT * from dysfunctional_database_table where not exists (SELECT * from current_database_table WHERE " & s & ")"
====
我尝试使用Linq来实现这一点,因为两种不同数据库类型的一些数据类型问题似乎不再那么令人头痛,
但我对林克是新手,完全被卡住了
我做到了这一点:
- 将旧表和新表作为dt1和dt2放入数据表中
Dim new_records = _ From new_recs In dt2.AsEnumerable Where Not ( _ From old_recs In dt1.AsEnumerable Where old_recs(field1) = new_recs(field1) AndAlso old_recs(field2) = new_recs(field2)).Any Select new_recs
有没有更简单的方法?我知道我可以使用JOIN或IN执行常见的EXISTS查询,在这种情况下,我不需要查询速度太快或其他任何东西。我不需要使用DataTable或DataSet—我可以将数据放在其他类型的对象中 所以我发现了很多使用MethodInfo和reflection之类的示例代码,但我无法让它们都正常工作-这些Datarows有一个Field方法,但它要求在Field name参数之前添加一个(of object)参数,这很难做到 所以我不确定这个解决方案是否是最有效的方法,但至少它是有效的。我很想知道这种方法是否有效,为什么有效。似乎大多数人都用反射来做这类事情,但我无法让它正常工作,不管怎样,我试图做的是非常简单的,而那些方法非常复杂。我想我是用SQL思维来做Linq的,但不管怎样,它是有效的
Dim f As Func(Of DataRow, DataRow, String, Boolean) = Function(d1 As DataRow, d2 As DataRow, s As String)
Dim fields = Split(s, ",")
Dim results As Boolean = True
For k As Integer = 0 To UBound(fields)
Dim obj = DataRowExtensions.Field(Of Object)(d1, fields(k))
Dim obj2 = DataRowExtensions.Field(Of Object)(d2, fields(k))
If obj <> obj2 Then results = False : Exit For
Next
Return results
End Function
Dim new_records = _
From new_recs In dt2.AsEnumerable.AsQueryable()
Where Not ( _
From old_recs In dt1.AsEnumerable.AsQueryable Where f(old_recs, new_recs, id_key)).Any
Select new_recs
Try
Return new_records.CopyToDataTable
Catch ex As Exception
Stop
End Try
Dim f As Func(属于数据行、数据行、字符串、布尔)=函数(d1作为数据行,d2作为数据行,s作为字符串)
尺寸字段=拆分(“,”)
将结果调整为布尔值=真
对于k,整数=0到UBound(字段)
Dim obj=DataRowExtensions.Field(对象的)(d1,fields(k))
Dim obj2=DataRowExtensions.Field(对象的)(d2,fields(k))
如果obj obj2,则结果=False:退出
下一个
返回结果
端函数
Dim new_记录=_
来自dt2.AsEnumerable.AsQueryable()中的新记录
何处没有(_
来自dt1.AsEnumerable.AsQueryable中的旧记录,其中f(旧记录、新记录、id密钥))。任意
选择新记录
尝试
返回新的\u records.CopyToDataTable
特例
停止
结束尝试
Dim f As Func(Of DataRow, DataRow, String, Boolean) = Function(d1 As DataRow, d2 As DataRow, s As String)
Dim fields = Split(s, ",")
Dim results As Boolean = True
For k As Integer = 0 To UBound(fields)
Dim obj = DataRowExtensions.Field(Of Object)(d1, fields(k))
Dim obj2 = DataRowExtensions.Field(Of Object)(d2, fields(k))
If obj <> obj2 Then results = False : Exit For
Next
Return results
End Function
Dim new_records = _
From new_recs In dt2.AsEnumerable.AsQueryable()
Where Not ( _
From old_recs In dt1.AsEnumerable.AsQueryable Where f(old_recs, new_recs, id_key)).Any
Select new_recs
Try
Return new_records.CopyToDataTable
Catch ex As Exception
Stop
End Try