使用子查询中的动态字段将双表存在查询从SQL转换为Linq



我正在尝试查询旧的Access数据库表,并将它们与SQL Server表进行比较。它们通常没有主键,或者它们有额外的字段,在90年代有一些用途,等等,或者新表有新字段,等等。

我需要根据运行时指定的一组字段来查找一个表中的记录,而不是另一个表。

因此,当我比较不同表中的数据时,我一直在SQL中进行这种查询:

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
    

但我不知道如何在飞行中加入这个部分——old_recs(field1)=new_recs

到目前为止,我已经尝试过:把我想比较的字段放在一个字符串中,然后把这个字符串作为一个变量(我想我可能作弊了,我想我作弊了)

dim str = old_recs(field1) = new_recs(field1) AndAlso old_recs(field2) = new_recs(field2)
 From new_recs In dt2.AsEnumerable
            Where Not ( _
                From old_recs In dt1.AsEnumerable Where str).Any
             Select new_recs

它告诉我它不能转换一个布尔-

如果没有Linq表达式,有什么方法可以做到这一点吗?它们似乎比我在这里要做的要复杂得多,而且它们需要大量的代码,而且我似乎找不到比较子查询中两个字段的表达式示例。

有没有更简单的方法?我知道我可以使用JOIN或IN来执行通常的EXISTS查询——在这种情况下,我不需要查询速度极快。而且我不需要使用DataTable或DataSet——我可以将数据放在其他类型的对象中。

所以我发现了很多使用MethodInfo和反射之类的示例代码,但我无法让它们发挥作用-这些Datarows有一个Field方法,但它需要在字段名参数之前添加一个(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

相关内容

  • 没有找到相关文章

最新更新