Вы можете использовать LINQ Entity Data Reader , чтобы записать список IEnumerable в базу данных, используя SQL Bulk Copy за кулисами.Вы можете использовать эту библиотеку для массовой загрузки результатов запроса LINQ прямо в базу данных, поскольку результаты запроса LINQ являются IEnumerable.
Поскольку существуют адаптеры LINQ-to-everything, вы можете выполнять такие приемы, какиспользуйте библиотеку LINQ to CSV , чтобы извлечь данные из CSV-файла с помощью запроса LINQ, затем LINQ Entity Data Reader для массовой записи этих данных непосредственно в базу данных.
Пример:
Проблема: быстро прочитать файл .csv в базу данных.Соединение с базой данных SQL осуществляется через LINQ-to-Entitys из C #.
Решение 1: Использование LINQ to CSV library , создание запроса LINQ для извлеченияданные, которые вы хотите, затем запишите их, используя стандартные вызовы LINQ-to-Entity (ctx.AddObject (), ctx.SaveChanges () и т. д.).Потребовалось время: 30 секунд для 20 000 записей, поскольку LINQ заканчивает генерацией запроса для каждой отдельной записи (slooooow !!!!!).
Решение 2: Используйте LINQ to CSV library , создайте запрос LINQ для извлечения необходимых данных в IEnumerable, используйте LINQ Entity Data Reader , чтобы массово записать эти данные непосредственно в целевую таблицу данных.Требуемое время: 3 секунды для 20 000 записей.
Решение 3: Использование хранимой процедуры с SQL-копированием.Время: 2 секунды для 20 000 записей.Однако это решение довольно хрупкое, поскольку оно опирается на хранимую процедуру, а массовое копирование SQL просто несовместимо с некоторыми форматами файлов .csv.Этот метод также требует, чтобы вы использовали промежуточную таблицу между фактической целевой таблицей и файлом .csv, чтобы справиться с проблемами форматирования файлов и помочь с нормализацией.
И вот исходный код для решения № 2:
static void WriteCSVtoSQLtable()
{
// Step 1: Read .csv file into IEnumerable using LINQ-to-CSV class.
// This section requires "LINQtoCSV" class as described at http://www.codeproject.com/KB/linq/LINQtoCSV.asp
string inputFilePath = @"T:\x.csv";
CsvFileDescription inputFileDescription = new CsvFileDescription
{
SeparatorChar = ',',
FirstLineHasColumnNames = true
};
IEnumerable<MyCustomColumnMappingClass> csvChains = cc.Read<MyCustomColumnMappingClass>(inputFilePath, inputFileDescription);
// Step 2: Now write into the target table on SQL Server.
// This section requires "EntityDataReader" class described at http://archive.msdn.microsoft.com/LinqEntityDataReader.
public static string dbSqlConnectionString = @";Data Source=(local);Initial Catalog=PhiEngine;Integrated Security=True;MultipleActiveResultSets=True";
SqlConnection dbSql(dbSqlConnectionString);
using (var tran = dbSql.BeginTransaction())
{
var csvFile = from p in csvChains
select p;
SqlBulkCopy bc = new SqlBulkCopy(dbSql,
SqlBulkCopyOptions.CheckConstraints |
SqlBulkCopyOptions.FireTriggers |
SqlBulkCopyOptions.KeepNulls, tran)
{
BatchSize = 1000,
DestinationTableName = "TStagingTable" // Temporary staging table in database.
};
bc.WriteToServer(csvFile.AsDataReader()); // Extension method .AsDataReader depends on adding the EntityDataReader class to your C# project (see above).
tran.Commit();
}
}
// This class is used by LINQ to CSV to query the .csv file, see "LINQtoCSV" website.
public class MyCustomColumnMappingClass
{
[CsvColumn(Name = "symbol", FieldIndex = 1)]
public string Symbol { get; set; }
[CsvColumn(Name = "date", FieldIndex = 3, OutputFormat = @"MM/dd/yyyy")]
public DateTime Date { get; set; }
}