棘手的LINQ查询:返回包含最大长度子字符串的子字符串的字符串

jon*_*ana 0 linq vb.net

我有2个数据表,每个数据表有300,000行(从带有OLEDB的2个excel工作表导入的数据表).

第一个数据表是'dtTosearch',第二个数据表是'sourceDt'.

这是2个表的示例:

数据表示例

我需要为'untagged'列(sourceDt)中的每一行找到'token'列(dtTosearch)中每一行的匹配项.匹配条件是:

  1. 'site'value ='site'值
  2. 'cat'值='类别'值
  3. 未标记的值必须包含标记值
  4. 如果上述所有条件都存在超过一个匹配,则查询必须返回 具有最大长度的令牌匹配. (这是我没有弄清楚如何使用linq执行的棘手部分)
  5. 这个任务必须在最短的处理时间内运行 - 因为它的要求,因为它更专业,因为我与朋友 - 同事-JAVA热心的开发人员打赌,.NET将运行得更快(如同白天( - :)

香港专业教育学院添加了代码的相关部分,它工作正常,但不是我想要的方式,我想改善处理时间,看看linqQuery()函数中的foreach循环 - 如果你帮我替换那个循环我会很感激通过将我的查询扩展到条件号4,循环操作条件4,因为linq查询的结果按'token'长度按降序排序,因此它将退出并返回具有最大行长度的结果.

Private Sub startScanning()
    Dim siteNum As Double
    Dim categoryNum As Double
    Dim stringToSearchin As String

    For i = 0 To sourceDt.Rows.Count - 1
        siteNum = sourceDt.Rows(i).Item(0)
        categoryNum = sourceDt.Rows(i).Item(1)
        stringToSearchin = sourceDt.Rows(i).Item(3)
       Debug.WriteLine( linqQuery(siteNum, categoryNum, stringToSearchin) & " " &
           stringToSearchin)
    Next
End Sub

Private Function linqQuery(ByVal sitenum As Double, ByVal cat As Double,
                           ByVal stringToSearchIn As String) As String

    Dim query = From row In dtTosearch
                Where (row.Field(Of Double?)("site") = sitenum And
                row.Field(Of Double?)("category") = cat)
                Order By row.Field(Of String)("token").Length Descending
                Select New With {
                    .token = row.Field(Of String)("token")
         }


    For Each x In query
        If stringToSearchIn.Contains(x.token) Then
            Return x.token
            Exit Function
        End If
    Next

    Return ""
End Function
Run Code Online (Sandbox Code Playgroud)

非常感谢您的时间和考虑!

Ger*_*old 5

在C#代码中,您可以找到所需的记录

from r1 in sourceDt.AsEnumerable()
join r2 in dtToSearch.AsEnumerable() 
    on new { p1 = r1.Field<int>("cat"), p2 = r1.Field<int>("Site") }
    equals new { p1 = r2.Field<int>("category"), p2 = r2.Field<int>("site") }
    into r2g
select new
{
    r1,
    p2 = (from r2 in r2g
          let token = r2.Field<string>("token")
          where token.Contains(r1.Field<string>("untagged"))
          orderby token.Length descending, token
          select r2).FirstOrDefault()
}
Run Code Online (Sandbox Code Playgroud)

也就是说,第一组将数据表连接在它们必须具有的共同字段上.该join - into语法使得这组加入作为解释在这里.

然后,在一组匹配的行中,过滤包含untaggedtokens 中的值的行,并返回具有最长令牌的行(如果长度上有绑定,则返回第一个的字母顺序).