简体   繁体   English

如何使用 LinQ 更新数据表中单行中的单列

[英]How to update a single column in single row in a datatable using LinQ

I'm working on a project that uses a Master database (a datatable) to drive downloading of files from an FTP server.我正在开发一个项目,该项目使用主数据库(数据表)来驱动从 FTP 服务器下载文件。 During the process, I create a local database (another datatable) for each client in the master database.在此过程中,我为 master 数据库中的每个客户端创建了一个本地数据库(另一个数据表)。 Here is the code that I use to create a client database:这是我用来创建客户端数据库的代码:

Console.WriteLine(" Building Client Database")
Clientdatabase = New DataTable
Clientdatabase = DataBaseTable.Clone
Dim RowList = (From row In DataBaseTable.AsEnumerable() Where (row.Field(Of String)("co") = CompanyID))
For Each RowItem In RowList
    Clientdatabase.ImportRow(RowItem)
Next

This code is working as expected;此代码按预期工作; the Clientdatabase is accurate in what it contains. Clientdatabase 包含的内容是准确的。 My problem is updating a field in the Clientdatabase.我的问题是更新 Clientdatabase 中的一个字段。 From within a loop, I'm getting each record that contains the full path and file name of the target file on the FTP server, then I attempt to update the clientdatabase with the local path and I can't get it to work.在循环中,我获取了包含 FTP 服务器上目标文件的完整路径和文件名的每条记录,然后我尝试使用本地路径更新客户端数据库,但无法使其正常工作。 From within the loop this code is performing the logic and downloading the file:在循环中,此代码正在执行逻辑并下载文件:

Dim FileList = (From row In DataBaseTable.AsEnumerable().Select(Function(x) New With {
     Key .co = x.Field(Of String)("co"),
     Key .path = x.Field(Of String)("path"),
     Key .OriginalFileName = x.Field(Of String)("OriginalFileName"),
     Key .DocumentID = x.Field(Of String)("DocumentID")
               }).Where(Function(s) s.co = CompanyID).ToList)
Console.Write(" Downloading Files : ")
Dim CursorArray() As String = Split("\,|,/,-", ",")
Dim FileCounter As Integer = 1
For Each CompanyFile In FileList
    Dim ThisFile As String = CompanyFile.path.Replace("\", "/")
    Dim Results As TransferOperationResult = DownloadFromPath(ThisFile, DestinPath)
    Dim TmpParts() As String = Split(ThisFile, "/")
    Dim LocalName As String = TmpParts(UBound(TmpParts))
    If Results.IsSuccess Then
        UpdateCDBPath(CompanyID, CompanyFile.DocumentID, LocalName)
        ReportData &= CompanyID & ",Success," & CompanyFile.OriginalFileName & "," & ThisFile & vbCrLf
    Else
        ReportData &= CompanyID & ",Failed," & CompanyFile.OriginalFileName & "," & ThisFile & vbCrLf
    End If
    FileCounter += 1
    Console.Write(CursorArray(FileCounter Mod 4) & Chr(8))
Next

The call to update (UpdateCDBPath) contains the following code:更新调用 (UpdateCDBPath) 包含以下代码:

Sub UpdateCDBPath(ByVal CompanyID As String, ByVal DocumentID As String, TargetValue As String)
    Dim result = (From row In Clientdatabase.AsEnumerable().Select(Function(x) New With {
                    Key .DocumentID = x.Field(Of String)("DocumentID"),
                    Key .Co = x.Field(Of String)("co")
                }).Where(Function(s) s.DocumentID = DocumentID And s.Co = CompanyID ) Select Clientdatabase)
    For Each ItemRow In result
        ItemRow.Rows(0).Item("Path") = TargetValue
    Next
End Sub

The problem is within this code block.问题出在这个代码块中。 DocumentID is a GUID that is unique within the client that uniquely identifies the document, TargetValue is the replacement path (local path to the file). DocumentID 是客户端内唯一标识文档的唯一 GUID,TargetValue 是替换路径(文件的本地路径)。 If I'm understanding the Linq correctly (and I'm not), it should only return the rows I'm interested in (1), thus how I'm setting the new path.如果我正确理解了 Linq(而我没有正确理解),它应该只返回我感兴趣的行 (1),因此我如何设置新路径。 I've tried countless examples from various examples and can't make it work.我已经尝试了各种示例中的无数示例,但无法使其工作。 When I check the Clientdatabase, none of the path fields are updated.当我检查 Clientdatabase 时,没有更新任何路径字段。 I've also confirmed that after saving the Clientdatabase locally, the fields are still the same.我还确认在本地保存 Clientdatabase 后,字段仍然相同。 Can some one please point me in the right direction, tell me where I went wrong or something so I can solve this.有人可以指出我正确的方向,告诉我哪里出了问题或什么,这样我就可以解决这个问题。 I eventually will need to update other fields in the clientdatabase;我最终需要更新客户端数据库中的其他字段; this is the first one.这是第一个。 Thanks in advance for any and all help that might come my way!在此先感谢您提供的任何帮助!

The linq for result is returning a EnumerableRowCollection(Of System.Data.DataTable) , meaning that it contains a list of rows that are the entire Clientdatabase . result的 linq 返回一个EnumerableRowCollection(Of System.Data.DataTable) ,这意味着它包含作为整个Clientdatabase的行列表。

As each row contains the entire DataRowCollection , ItemRow.Rows(0).Item("Path") = TargetValue will update only the first row in Clientdatabase as many times as there are records in results .由于每一行包含整个DataRowCollectionItemRow.Rows(0).Item("Path") = TargetValue将更新只在第一行Clientdatabase因为有记录中多次results

Changing the query to return an EnumerableRowCollection(Of System.Data.DataRow) allows each row to be accessed directly in a loop:更改查询以返回EnumerableRowCollection(Of System.Data.DataRow)允许在循环中直接访问每一行:

Sub UpdateCDBPath(ByVal CompanyID As String, ByVal DocumentID As String, TargetValue As String)
    Dim result = From row In Clientdatabase.AsEnumerable()
                 Where row.Field(Of String)("DocumentID") = DocumentID AndAlso
                       row.Field(Of String)("co") = CompanyID
                 Select row

    For Each ItemRow In result
        ItemRow.Item("Path") = TargetValue
    Next
End Sub

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM