2013-11-18 3 views
2

В нашем проекте мы используем Linq2SQL, но теперь мы должны иметь возможность быстро вставить почти 15k строк в таблице базы данных, поэтому я написал метод расширения:как настроить автоматическое отображение в SqlBulkCopy

public static void BulkInsertBigData(Table<Maintenance> maintenance, IEnumerable<Maintenance> maintenancesToInsert) 
    { 

      using (var copy = new SqlBulkCopy(maintenance.Context.Connection.ConnectionString, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.KeepNulls)) 
      { 
       //copy.ColumnMappings.Add("Id", "Id"); 
       //copy.ColumnMappings.Add("FacilityId", "FacilityId"); 
       //copy.ColumnMappings.Add("ParentFacilityId", "ParentFacilityId"); 
       //copy.ColumnMappings.Add("StartTime", "StartTime"); 
       //copy.ColumnMappings.Add("EndTime", "EndTime"); 
       //copy.ColumnMappings.Add("ExpirationTime", "ExpirationTime"); 
       //copy.ColumnMappings.Add("DispatcherUserName", "DispatcherUserName"); 
       copy.DestinationTableName = "dbo.Maintenance"; 
       var data = maintenancesToInsert.ToDataTable(); 
       copy.WriteToServer(data); 
      } 

    } 

Maintanance - это автоматически созданный класс Linq2SQL. Этот код отлично работает, когда я раскомментирую строки ColumnMappings, но они не подходят, потому что если кто-то изменит dbml, этот код не будет работать (этот код не является гибким :)). ToDataTable() - метод на основе отражения, который преобразует список обслуживания в DataTable.

Я буду благодарен за любую помощь

ответ

3

Как насчет:

public static void BulkInsertBigData<T>(Table<T> definition, IEnumerable<T> rows) 
{ 
    using (var copy = new SqlBulkCopy(definition.Context.Connection.ConnectionString, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.KeepNulls)) 
    { 
     var meta = definition.Context.Mapping.GetMetaType(typeof(T)); 
     foreach (var col in meta.DataMembers) 
     { 
      copy.ColumnMappings.Add(col.Member.Name, col.MappedName); 
     } 
     copy.DestinationTableName = meta.Table.TableName; 
     var data = rows.ToDataTable(); 
     copy.WriteToServer(data); 
    } 
} 

или даже лучше: избавиться от DataTable через FastMember:

public static void BulkInsertBigData<T>(Table<T> definition, IEnumerable<T> rows) 
{ 
    using (var copy = new SqlBulkCopy(definition.Context.Connection.ConnectionString, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.KeepNulls)) 
    { 
     var meta = definition.Context.Mapping.GetMetaType(typeof(T)); 
     var members = new List<string>(meta.DataMembers.Count); 
     foreach (var col in meta.DataMembers) 
     { 
      copy.ColumnMappings.Add(col.Member.Name, col.MappedName); 
      members.Add(col.Member.Name); 
     } 
     copy.DestinationTableName = meta.Table.TableName; 
     using (var reader = ObjectReader.Create(rows, members.ToArray())) 
     { 
      copy.WriteToServer(reader); 
     } 
    } 
} 
+0

Гравия, большое спасибо! Я использовал ваше первое решение, и оно отлично поработало для меня. –

Смежные вопросы