我正在尝试读取一个文本文件,然后根据其重要性分割每一行,从而在我的数据库表中形成一个特定的记录条目。我将这些记录存储在列表中,并将数据从列表批量插入到数据库中。我正在读取的文件大小约为 18MB,大约有 15,000 到 18,000 行。下面是代码:
StringBuilder logInsertCommand = new StringBuilder();
List<string> bulkLogInsert = new List<string>();
using (FileStream fs = File.Open(FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (BufferedStream bs = new BufferedStream(fs))
using (StreamReader sr = new StreamReader(bs, Encoding.GetEncoding("iso-8859-1")))
{
while ((line = sr.ReadLine()) != null)
{
//Perform some logic with `line` and get all the column values required for inserting a new record in database table. Values like FirstColumnValue, SecondColumnValue are obtained from the logic performed on `line` variable.
logInsertCommand.Append(FirstColumnValue).Append(';').Append(SecondColumnValue).Append(';').Append(ThirdColumnValue).Append(';').Append(FourthColumnValue).Append(';').Append(FifthColumnValue);
bulkLogInsert.Add(logInsertCommand.ToString());
}
}
public void InsertBulkLog(List<string> records)
{
try
{
String connectionString = ConfigurationManager.AppSettings["DBConString"];
DataTable table = new DataTable("TORNADO_LOGS");
table.Columns.Add(new DataColumn("FILENAME", typeof(string)));
table.Columns.Add(new DataColumn("PROJ_CODE", typeof(string)));
table.Columns.Add(new DataColumn("IS_RECORD_PROCESSED", typeof(string)));
table.Columns.Add(new DataColumn("FILE_LAST_MODIFIED_DATE", typeof(string)));
table.Columns.Add(new DataColumn("MP3_FILE", typeof(string)));
foreach (string record in records)
{
string[] rowParameters = record.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
table.Rows.Add(rowParameters);
}
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString))
{
bulkCopy.BulkCopyTimeout = 600;
bulkCopy.DestinationTableName = table.TableName;
bulkCopy.WriteToServer(table);
}
}
catch (Exception ex)
{
//Write to log
}
}
我的问题是,我将记录(15k 到 17k)存储在像列表这样的容器中,然后尝试将数据批量插入 SQL Server 我想这不是很好的方法,那么我如何才能有效地将这些数据插入到数据库?任何方法都会有帮助。
要将文件中的数据完全流式传输到 SQL 中,您需要创建一个
IDataReader
。
有很多方法可以做到这一点,但最简单的是使用 NuGet FastMember 库,它有
ObjectReader.Create
。它接受 IEnumerable<SomeType>
并返回 IDataReader
,您可以将其直接传递给 WriteToServer
。这意味着每一行都会流入批量复制中,并且您永远不会将整个文件一次存储在内存中。
private IEnumerable<RecordLine> GetRecords()
{
using (FileStream fs = File.Open(FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (StreamReader sr = new StreamReader(bs, Encoding.GetEncoding("iso-8859-1")))
{
string line;
while ((line = sr.ReadLine()) != null)
{
var rec = new RecordLine();
// use logic to create a RecordLine object here
yield return rec;
}
}
}
public void InsertBulkLog()
{
try
{
var connectionString = ConfigurationManager.AppSettings["DBConString"];
using (var reader = ObjectReader.Create(GetRecords());
using (var bulkCopy = new SqlBulkCopy(connectionString))
{
bulkCopy.BulkCopyTimeout = 600;
bulkCopy.DestinationTableName = table.TableName;
bulkCopy.WriteToServer(reader);
}
}
catch (Exception ex)
{
//Write to log
}
}