2011-06-25 62 views
2

我有1M的HTML文件,我需要解析,然後將提取的信息插入到我的SQL服務器。由於我已解析出的對象之間的關係,每個文件都分析出了多個表中的信息在SQL Server中並行插入多個項目到多個關係表中?

我現在正在使用實體框架來執行此操作,但是將我的每條信息添加到EF上下文中的適當對象上很長一段時間並沒有效率!我需要這個更快,特別是我有這麼多的文件來處理。

什麼是解析出大量文件的並行方式,並將其插入SQL服務器,你添加的項目有關係?

此外,有沒有更好的技術呢?像Informatica?

+0

我想知道你爲什麼在這種情況下使用EF?順便說一句。如果您需要在交易中添加該數據,您將無法使用並行方法。 –

+0

那麼,我有這個數據庫利用其餘的EF讀取和查詢,但我必須首先構建數據庫,我最初的嘗試是使用我已經建立在EF模型,但它是緩慢的。 – iCode

回答

0

我認爲SqlBulkCopy Class將是這種情況下的最佳選擇。

您可以在SqlBulkCopy類中製作通用包裝,這將允許您在任何實體上使用SqlBulkCopy。下面是LINQ到SQL的包裝器,但同樣的想法可以與實體框架一起使用,假設您的實體一對一映射到表。

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); 
     } 
    } 
} 
+0

問題是,我需要將每個解析出的對象及其相關對象一次保存到多個表中,以維持關係。聽起來像SqlBulkCopy只會持續到一個表,但如果我需要堅持多個表的主鍵都是自動生成的?我不確定我的問題是否清楚。 – iCode

+0

@Mike Dotnet - 如果你想在每一行插入後返回id,那麼你就沒有其他選擇,因爲這樣做是逐行的。您可以使用事務來加速這一點(以避免多次日誌更新)。另一種選擇是使用'OUTPUT'語句插入並返回插入ID列表的存儲過程。 –

+0

我無法跟進。是否有任何代碼示例可以引用我的意思? – iCode

相關問題