[英]How to use transaction in C#.net
我想以很高的速度将数据插入sqlserver。 因此,我在c#.net中使用事务,但是在使用事务之后,我注意到插入速度与不使用它没有区别。 请检查我的代码并帮助我解决它。
代码:
void ReadToTable()
{
try
{
if (dir != "")
{
dic.Clear();
string[] lines = System.IO.File.ReadAllLines(dir);
foreach (string line in lines)
{
SqlConnection sqlconn = new SqlConnection(DBsetting.Connstring);
sqlconn.Open();
SqlTransaction transaction = sqlconn.BeginTransaction();
if (!string.IsNullOrEmpty(line))
{
l = line.Split('\t');
l[0] = l[0].Trim();
l[1] = l[1].Trim();
l[2] = l[2].Trim();
l[3] = l[3].Trim();
if (!string.IsNullOrEmpty(l[0]) && l[3] == "1" || l[3] == "0")
{
dic.Add(new KeyValuePair<string, string>(l[0], l[1]));
PersianCalendar persCal = new PersianCalendar();
SqlCommand sqlda = new SqlCommand("insert into readd(IDp,date,day,nobatkari)values(@IDp,@date,@day,@nobatkari)", sqlconn, transaction);
sqlda.Transaction = transaction;
sqlda.Parameters.AddWithValue("@date", l[1]);
sqlda.Parameters.AddWithValue("@IDp", l[0]);
sqlda.Parameters.AddWithValue("@day", GetDayOfWeek(GetPerDate(l[1])));
sqlda.Parameters.AddWithValue("@nobatkari", "");//ntkari[idx].ToString());
sqlda.ExecuteNonQuery();
transaction.Commit();
sqlconn.Close();
sqlconn.Dispose();
}
else
{
ReadDataAndInsertIntoTable(line);
}
}
}
RefGrid();
foreach (var pair in dic)
{
InsertNobatKari(pair.Key, GetPerDate(pair.Value).ToString());
}
}
}
catch (Exception ex)
{
if (ex.Message.Contains("there is no row at position 0"))
{
MessageBox.Show("لطفا سطر خالی را انتخاب ننمایید");
}
else if (ex.Message.Contains("Cannot insert duplicate key row in object"))
{
MessageBox.Show("امکان ورود سطر تکراری وجود ندارد");
}
else
{
MessageBox.Show(ex.Message);
}
}
finally
{
}
}
我想以很高的速度将数据插入sqlserver。因此我在c#.net中使用事务,但是在使用事务后,我注意到插入速度与不使用它没有区别。
是的,您不会看到改善,因为交易不是为了提高速度。 另外,您没有正确使用事务:您没有提交事务。
您的方法
想想你在做什么。 您正在循环一个文件中的行,并为每一行创建一个数据库连接,然后一直到数据库插入一条记录。 您执行n次,其中n是您的文本文件中的记录数。
另一件事是您正在使用File.ReadAllLines
,它将把整个文件读入内存:如果文件真的很大怎么办? 你的记忆能应付吗?
更好的方法
更好的方法是创建一个连接,然后转到数据库并获取一批记录(50、100或更多),然后一次完成。 继续执行此操作,直到所有记录都输入为止。
另外,您应该使用File.ReadLines
以便它会延迟读取每一行(一旦被请求,它将把该行加载到内存中)。
要提高速度,请使用SqlBulkCopy 。 确保您阅读了有关列映射的部分。
脚步:
在这一行的基础上,创建您的内存表结构。
string[] strArray = line.Split('\\t'); var dt = new DataTable(); for (int index = 0; index < strArray.Length; index++) dt.Columns.Add(new DataColumn());
从文件填充内存数据表:
do { DataRow row = dt.NewRow(); string[] itemArray = line.Split('\\t'); row.ItemArray = itemArray; dt.Rows.Add(row); i = i + 1; line = sr.ReadLine(); } while (!string.IsNullOrEmpty(line));
将数据发送到数据库:
var bc = new SqlBulkCopy(dbConn, SqlBulkCopyOptions.TableLock, null) { DestinationTableName = "TestData", BatchSize = dt.Rows.Count }; dbConn.Open(); bc.WriteToServer(dt); dbConn.Close(); bc.Close();
如果文件很大,则可以分批执行步骤4。 在上面的代码中, sr
变量将是StreamReader
一个实例,但是无论如何您都可以使用它来读取文件。
注意:
此代码不可复制粘贴,而只是作为指导,因此您需要对其进行调整以适合您的需求。
您为插入的每行创建一个事务,这与不进行事务的所有操作几乎相同。 您可能应该执行以下操作:
string[] lines = System.IO.File.ReadAllLines(dir);
SqlConnection sqlconn = new SqlConnection(DBsetting.Connstring);
sqlconn.Open();
SqlTransaction transaction = sqlconn.BeginTransaction();
foreach (string line in lines)
{
...
}
transaction.Commit();
sqlconn.Close();
sqlconn.Dispose();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.