【问题标题】:Dynamic join clause linq动态连接子句 linq
【发布时间】:2018-07-26 11:09:27
【问题描述】:

是否可以构建动态 linq 查询。我的问题是连接条件可能是一对多。不同场景下要加入的字段数会有所不同。

 dim data = (From drow As DataRow In dtDistinctRecords.Rows
             Join mainSourceRow As DataRow In mainSource.Rows
             On drow.Field(Of String)(var0) Equals mainSourceRow.Field(Of String)(var0)
                 And drow.Field(Of String)(var1) Equals mainSourceRow.Field(Of String)(var1)
                 And drow.Field(Of String)(var2) Equals mainSourceRow.Field(Of String)(var2)
                 And drow.Field(Of String)(var3) Equals mainSourceRow.Field(Of String)(var3)

上述问题的解决方法如下: 这段代码适用于设置选项推断(在项目属性上可用)但不能关闭。我有一个旧版应用程序设置了此选项。 仍然无法将选项推断设置为关闭。

 Private Sub SurroundingSub()
    Dim columnNames As String() = {"MyColumn1", "MyColumn2"}
    Dim dt As DataTable = New DataTable()
    dt.Columns.Add("MyColumn", GetType(String))
    dt.Columns.Add("MyColumn1", GetType(String))
    dt.Columns.Add("MyColumn2", GetType(String))
    dt.Columns.Add("Data", GetType(String))

    For i As Integer = 0 To 10 - 1
      Dim dr As DataRow = dt.NewRow()
      dr("MyColumn") = "MyColumn" & i
      dr("MyColumn1") = "MyColumn1" & i
      dr("MyColumn2") = "MyColumn2" & i
      dr("Data") = "Data1" & i
      dt.Rows.Add(dr)
    Next

    Dim dt1 As DataTable = New DataTable()
    dt1.Columns.Add("MyColumn", GetType(String))
    dt1.Columns.Add("MyColumn1", GetType(String))
    dt1.Columns.Add("MyColumn2", GetType(String))
    dt1.Columns.Add("Data", GetType(String))

    For i As Integer = 0 To 5 - 1
      Dim dr As DataRow = dt1.NewRow()
      dr("MyColumn") = "MyColumn" & i
      dr("MyColumn1") = "MyColumn1" & (i)
      dr("MyColumn2") = "MyColumn2" & (i)
      dr("Data") = "Data2" & i
      dt1.Rows.Add(dr)
    Next

    dt1.Rows(0)("MyColumn1") = "MyColumn111"
    dt1.Rows(1)("MyColumn2") = "MyColumn888"
    Dim data = (From dr In dt.AsEnumerable() Join dr1 In dt1.AsEnumerable() On dr("MyColumn") Equals dr1("MyColumn") Select New With {.Dr = dr, .Dr1 = dr1
          })


 **'It fails here**
 For Each column As String In columnNames

   Dim columnname = column
   data = data.Where(Function(x) x.dr.Field(Of String)(columnname) = 
   x.dr1.Field(Of String)(columnname))
 Next

    Dim value = data.[Select](Function(x) x.dr1).CopyToDataTable()
  End Sub

【问题讨论】:

    标签: .net vb.net linq dynamic-linq


    【解决方案1】:

    作弊(有点):如果你有一个inner join,把条件放在On部分的join或者Where是等价的,如果你有多个条件在And一个Where,将 Where 拆分为多个 Where 是等价的。

    所以你可以:

    Dim data = From drow as DataRow In dtDistinctRecords.Rows 
               From mainSourceRow In mainSource.Rows 
               Select New With { drow, mainSourceRow }
    
    If cond1 Then
        data = data.Where(Function(x) x.drow.Field(Of String)("var0") = x.mainSourceRow.Field(Of String)("var0"))
    End If
    
    If cond2 Then
        data = data.Where(Function(x) x.drow.Field(Of String)("var1") = x.mainSourceRow.Field(Of String)("var1"))
    End If
    

    【讨论】:

    • @arjun 那么你将如何决定要添加哪些条件?
    • 我有一个必须应用连接的列名列表。在 sql 中,我们可以构建构建字符串并运行它。我想知道我是否可以在这里做类似的事情。
    • @arjun 是的,你可以在列列表上做一个For Each循环,并在x.drow.Field(Of String)(colName) = x.mainSourceRow.Field(Of String)(colName)中传递列名
    • 如果我想一次对多个字段应用 where 条件而不是一次应用一个。
    • @arjun 我写的没有区别。 linq是懒惰的,直到你枚举它,它什么都不做,多个Where相当于一个大Where
    猜你喜欢
    • 2023-04-10
    • 2014-07-31
    • 1970-01-01
    • 2016-01-12
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 2010-10-25
    相关资源
    最近更新 更多