DataTable 删除 SQL Server 中未反映的行

Posted

技术标签:

【中文标题】DataTable 删除 SQL Server 中未反映的行【英文标题】:DataTable Remove Rows Not Reflected in SQL Server 【发布时间】:2015-05-28 14:00:44 【问题描述】:

我对 C# 还很陌生,这让我很困惑。我的项目使用 DataTables 和 TableAdapters 连接到 SQL Server 数据库。我有一个方法可以打开 Excel,构建一个 DataRow,然后将其传递给下面的方法,该方法通过 TableAdapter (ctaJETS) 将其添加到我的 DataTable (cdtJETS)。

    public bool AddJETSRecord(DataRow JETSDataRow)
    
        bool bolException = false;
        cdtJETS.BeginLoadData();
        // Add the data row to the table
        try
        
            cdtJETS.ImportRow(JETSDataRow);
        
        catch (Exception e)
        
            // Log an exception
            bolException = true;
            Console.WriteLine(e.Message);
        
        cdtJETS.EndLoadData();
        // If there were no errors and no exceptions, then accept the changes
        if (!cdtJETS.HasErrors && !bolException)
        
            ctaJETS.Update(cdtJETS);
            return true;
        
        else
            return false;
    

以上工作正常,记录按预期显示在 SQL Server 中。我有另一种方法,它获取该 DataTable 中的记录子集并将它们输出到另一个 Excel 文件(这是一个批处理过程,将使用上述方法随着时间的推移收集记录,然后偶尔输出它们,所以我不能直接移动从第一个 Excel 文件到第二个的数据)。更新第二个 Excel 文件后,我想从表中删除记录,以便下次运行该方法时不会重复它们。这就是我遇到问题的地方:

    public bool DeleteJETSRecords(DataTable JETSData)
    
        int intCounter = 0;
        DataRow drTarget;
        // Parse all of the rows in the JETS Data that is to be deleted
        foreach (DataRow drCurrent in JETSData.Rows)
        
            // Search the database data table for the current row's OutputID
            drTarget = cdtJETS.Rows.Find(drCurrent["OutputID"]);
            // If the row is found, then delete it and increment the counter
            if (drTarget != null)
            
                cdtJETS.Rows.Remove(drTarget);
                intCounter++;
            
        

        // Continue if all of the rows were found and removed
        if (JETSData.Rows.Count == intCounter && !cdtJETS.HasErrors)
        
            cdtJETS.AcceptChanges();
            try
            
                ctaJETS.Update(dtJETS);
            
            catch (Exception)
            
                throw;
            
            return true;
        
        else
            cdtJETS.RejectChanges();
            return false;
    

当我逐步执行该方法时,我可以看到从 DataTable 中删除的行(即,如果 JETSData 有 10 行,最后 cdtJETS 有 n-10 行)并且没有抛出异常,但是在我接受更改并更新之后TableAdapter,底层记录还在我的 SQL Server 表中。我错过了什么?

【问题讨论】:

【参考方案1】:

The Rows.Remove method 相当于调用the row's Delete method,后跟the row's AcceptChanges method。

与the DataTable.AcceptChanges method 一样,这表明更改已经保存到数据库中。这不是你想要的。

以下应该有效:

public bool DeleteJETSRecords(DataTable JETSData)

    int intCounter = 0;
    DataRow drTarget;
    // Parse all of the rows in the JETS Data that is to be deleted
    foreach (DataRow drCurrent in JETSData.Rows)
    
        // Search the database data table for the current row's OutputID
        drTarget = cdtJETS.Rows.Find(drCurrent["OutputID"]);
        // If the row is found, then delete it and increment the counter
        if (drTarget != null)
        
            drTarget.Delete();
            intCounter++;
        
    

    // Continue if all of the rows were found and removed
    if (JETSData.Rows.Count == intCounter && !cdtJETS.HasErrors)
    
        // You have to call Update *before* AcceptChanges:
        ctaJETS.Update(dtJETS);
        cdtJETS.AcceptChanges();
        return true;
    

    cdtJETS.RejectChanges();
    return false;

【讨论】:

像魅力一样工作。非常感谢@richard。

以上是关于DataTable 删除 SQL Server 中未反映的行的主要内容,如果未能解决你的问题,请参考以下文章

将 DataTable 的所有行插入到 SQL Server 表中,包括 Id 值

通过数据库上下文将空 DataTable 传递给 SQL Server 存储过程

DataTable 到带有实体框架的 SQL Server 表

从 SQL Server 数据库填充 DataTable

如何使用SQL Server中的DataTable模拟“批量”插入

C#需要存储一个解析后的SQL Server表,使用datatable或者list