为了在数据库中插入大量数据,我将所有插入信息收集到一个列表中,并将该列表转换为DataTable.然后,我通过SqlBulkCopy将该列表插入数据库.

在这里,我发送生成的列表
LiMyList
,其中包含我要插入数据库的所有批量数据的信息
,并将其传递给批量插入操作

InsertData(LiMyList, "MyTable");

其中InsertData

 public static void InsertData<T>(List<T> list,string TableName)
        {
                DataTable dt = new DataTable("MyTable");
                clsBulkOperation blk = new clsBulkOperation();
                dt = ConvertToDataTable(list);
                ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
                using (SqlBulkCopy bulkcopy = new SqlBulkCopy(ConfigurationManager.ConnectionStrings["SchoolSoulDataEntitiesForReport"].ConnectionString))
                {
                    bulkcopy.BulkCopyTimeout = 660;
                    bulkcopy.DestinationTableName = TableName;
                    bulkcopy.WriteToServer(dt);
                }
        }    

public static DataTable ConvertToDataTable<T>(IList<T> data)
        {
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
            DataTable table = new DataTable();
            foreach (PropertyDescriptor prop in properties)
                table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
            foreach (T item in data)
            {
                DataRow row = table.NewRow();
                foreach (PropertyDescriptor prop in properties)
                    row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
                table.Rows.Add(row);
            }
            return table;
        }

现在我想做一个更新操作,有没有办法插入数据是由SqlBulkCopy完成的,用于将数据从C#更新到数据库.Net

推荐答案

我之前所做的是从数据向临时表执行大容量插入,然后使用命令或存储过程更新将临时表与目标表相关联的数据.临时表是一个额外的步骤,但是与逐行更新数据相比,如果行数很大,则使用大容量插入和大容量更新可以提高性能.

例子:

public static void UpdateData<T>(List<T> list,string TableName)
{
    DataTable dt = new DataTable("MyTable");
    dt = ConvertToDataTable(list);

    using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SchoolSoulDataEntitiesForReport"].ConnectionString))
    {
        using (SqlCommand command = new SqlCommand("", conn))
        {
            try
            {
                conn.Open();

                //Creating temp table on database
                command.CommandText = "CREATE TABLE #TmpTable(...)";
                command.ExecuteNonQuery();

                //Bulk insert into temp table
                using (SqlBulkCopy bulkcopy = new SqlBulkCopy(conn))
                {
                    bulkcopy.BulkCopyTimeout = 660;
                    bulkcopy.DestinationTableName = "#TmpTable";
                    bulkcopy.WriteToServer(dt);
                    bulkcopy.Close();
                }

                // Updating destination table, and dropping temp table
                command.CommandTimeout = 300;
                command.CommandText = "UPDATE T SET ... FROM " + TableName + " T INNER JOIN #TmpTable Temp ON ...; DROP TABLE #TmpTable;";
                command.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                // Handle exception properly
            }
            finally
            {
                conn.Close();
            }
        }
    }
}

请注意,使用单个连接执行整个操作,以便能够在每个步骤中使用临时表,因为临时表的范围是每个连接.

.net相关问答推荐

将Visual Studio更新到v17.9.3后,IDE关闭,dotnet.exe命令报告致命错误.内部CLR错误.(0x80131506)

删除数据库项目中的表

Powershell机器令牌组

使用CLR将数据从Excel导入SQL Server时出错

如何在 Raspberry Pi 上托管 WASM 文件?

.Net MAUI Android 无法与 API localhost 对话

在接口内部声明 IEnumerable 而在具体类中声明 IList

StreamWriter.Flush() 和 StreamWriter.Close() 有什么区别?

如何使用 C# 中的代码更改网络设置(IP 地址、DNS、WINS、主机名)

在 .NET C# 中存储加密密钥的最佳方式

ILMerge 最佳实践

指定的版本字符串不符合要求的格式 - major[.minor[.build[.revision]]]

实体框架 - 无法将 lambda 表达式转换为类型字符串,因为它不是委托类型

ASP.NET Core 等效于 ASP.NET MVC 5 的 HttpException

找不到 Assert.Fail 和 Assert.Pass 或等效项

VB.NET 与 C# 整数除法

C# 相当于 Java 的 Exception.printStackTrace()?

如何判断枚举是否包含数字?

从 bcp 客户端接收到 colid 6 的无效列长度

多行 C# 插值字符串文字