Вставить много элементов в несколько таблиц отношений параллельно в SQL Server? - PullRequest
2 голосов
/ 25 июня 2011

У меня есть 1M html-файлов, которые мне нужно проанализировать, а затем вставить извлеченную информацию в мой sql-сервер. Каждый анализируемый файл заканчивается в нескольких таблицах из-за связей между объектами, которые я проанализировал

Я сейчас использую Entity Framework для этого, но добавление каждой части моей информации в соответствующий объект в контексте EF занимает много времени и неэффективно! Мне нужно это быстрее, особенно потому, что у меня так много файлов для обработки.

Каков быстрый способ параллельного анализа большого количества файлов и их вставки в SQL-сервер, где добавляемые элементы имеют взаимосвязи?

Кроме того, есть ли лучшая технология для этого? Нравится Informatica?

1 Ответ

0 голосов
/ 25 июня 2011

Я думаю, SqlBulkCopy Class будет лучшим вариантом в этом случае.

Вы можете создать универсальную оболочку для класса SqlBulkCopy, которая позволит вам использовать SqlBulkCopy для любой сущности. Ниже приведена обертка для LINQ-to-SQL, но та же идея будет работать с Entity Framework, при условии, что ваша сущность сопоставлена ​​с таблицами один-к-одному.

public void BulkInsert<TBusinessObject>(IEnumerable<TBusinessObject> entities, int timeoutInSeconds)
    where TBusinessObject : class, IBusinessObject
{
    AssertUtilities.ArgumentAllNotNull(entities, "entities");
    AssertUtilities.ArgumentNotNegative(timeoutInSeconds, "timeoutInSeconds");

    var metaTable = Mapping.GetTable(typeof(TBusinessObject));
    if (metaTable == null)
        throw new DataAccessException("MetaTable is not found.");
    var insertDataMembers = metaTable.RowType.PersistentDataMembers
        .Where(arg => !arg.IsDbGenerated)
        .OrderBy(arg => arg.Ordinal)
        .ToList();
    using (var dataTable = new DataTable())
    {
        dataTable.Locale = CultureInfo.InvariantCulture;
        var dataColumns = insertDataMembers
            .Select(arg => new DataColumn(arg.MappedName))
            .ToArray();
        dataTable.Columns.AddRange(dataColumns);
        foreach (var entity in entities)
        {
            var itemArray = insertDataMembers
                .Select(arg => arg.StorageAccessor.GetBoxedValue(entity))
                .ToArray();
            dataTable.Rows.Add(itemArray);
        }
        try
        {
            if (Connection.State != ConnectionState.Open)
                Connection.Open();
            var sqlConnection = (SqlConnection)Connection;
            var sqlTransaction = (SqlTransaction)Transaction;
            using (var bulkCopy = new SqlBulkCopy(sqlConnection, SqlBulkCopyOptions.Default, sqlTransaction))
            {
                bulkCopy.BulkCopyTimeout = timeoutInSeconds;
                bulkCopy.DestinationTableName = metaTable.TableName;
                foreach (var dataColumn in dataColumns)
                    bulkCopy.ColumnMappings.Add(dataColumn.ColumnName, dataColumn.ColumnName);
                bulkCopy.WriteToServer(dataTable);
            }
        }
        catch (Exception exception)
        {
            throw DataAccessExceptionTranslator.Translate(exception);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...