private void WriteToServer(ISqlCeBulkCopyInsertAdapter adapter) { CheckDestination(); if (_conn.State != ConnectionState.Open) { _conn.Open(); } GetAndDropConstraints(); List <KeyValuePair <int, int> > map; int totalRows = 0; SqlCeTransaction localTrans = _trans ?? _conn.BeginTransaction(); if (ColumnMappings.Count > 0) { //mapping are set, and should be validated map = ColumnMappings.ValidateCollection(_conn, localTrans, adapter, _keepNulls, _destination); } else { //create default column mappings map = SqlCeBulkCopyColumnMappingCollection.Create(_conn, localTrans, adapter, _keepNulls, _destination); } using (var cmd = new SqlCeCommand(_destination, _conn, localTrans)) { cmd.CommandType = CommandType.TableDirect; using (var rs = cmd.ExecuteResultSet(ResultSetOptions.Updatable)) { var idOrdinal = SqlCeBulkCopyTableHelpers.IdentityOrdinal(_conn, localTrans, _destination); var rec = rs.CreateRecord(); var rowCounter = 0; IdInsertOn(localTrans, idOrdinal); //Converting to an array removed the perf issue of a list and foreach statement. var cm = map.ToArray(); while (adapter.Read()) { if (adapter.SkipRow()) { continue; } for (var i = 0; i < cm.Length; i++) { //caching the values this way do not cause a perf issue. var sourceIndex = cm[i].Key; var destIndex = cm[i].Value; // Let the destination assign identity values if (!_keepIdentity && destIndex == idOrdinal) { continue; } //determine if we should ever allow this in the map. if (sourceIndex < 0) { continue; } var value = sourceIndex > -1 ? adapter.Get(sourceIndex) : null; if (value != null && value.GetType() != DbNullType) { rec.SetValue(destIndex, value); } else { //we can't write to an auto number column so continue if (_keepNulls && destIndex == idOrdinal) { continue; } if (_keepNulls) { rec.SetValue(destIndex, DBNull.Value); } else { rec.SetDefault(destIndex); } } } rowCounter++; totalRows++; try { rs.Insert(rec); } catch (SqlCeException ex) { if (ex.NativeError == 25016 && _ignoreDuplicateErrors) //A duplicate value cannot be inserted into a unique index. { System.Diagnostics.Trace.TraceWarning("SqlCeBulkCopy: Duplicate value error was ignored"); continue; } else { throw; } } // Fire event if needed if (RowsCopied != null && _notifyAfter > 0 && rowCounter == _notifyAfter) { FireRowsCopiedEvent(totalRows); rowCounter = 0; } } IdInsertOff(localTrans, idOrdinal); if (RowsCopied != null) { FireRowsCopiedEvent(totalRows); } } } //if we have our own transaction, we will commit it if (_trans == null) { localTrans.Commit(CommitMode.Immediate); localTrans.Dispose(); } ResetSeed(totalRows); RestoreConstraints(); }
private void WriteToServer(ISqlCeBulkCopyInsertAdapter adapter) { CheckDestination(); if (conn.State != ConnectionState.Open) { conn.Open(); } List <KeyValuePair <int, int> > mappings = null; if (Mappings.Count > 0) { //mapping are set, and should be validated mappings = Mappings.ValidateCollection(conn, adapter, options, destination); } else { //create default column mappings mappings = SqlCeBulkCopyColumnMappingCollection.Create(conn, adapter, options, destination); } SqlCeTransaction localTrans = trans ?? conn.BeginTransaction(); using (SqlCeCommand cmd = new SqlCeCommand(destination, conn, localTrans)) { cmd.CommandType = CommandType.TableDirect; using (SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.Updatable)) { int idOrdinal = SqlCeBulkCopyTableHelpers.IdentityOrdinal(conn, options, destination); SqlCeUpdatableRecord rec = rs.CreateRecord(); int rowCounter = 0; int totalRows = 0; IdInsertOn(); //Converting to an array removed the perf issue of a list and foreach statement. var cm = mappings.ToArray(); while (adapter.Read()) { if (adapter.SkipRow()) { continue; } for (int i = 0; i < cm.Length; i++) { //caching the values this way do not cause a perf issue. var sourceIndex = cm[i].Key; var destIndex = cm[i].Value; // Let the destination assign identity values if (!keepIdentity && destIndex == idOrdinal) { continue; } //determine if we should ever allow this in the map. if (sourceIndex < 0) { continue; } var value = sourceIndex > -1 ? adapter.Get(sourceIndex) : null; if (value != null && value.GetType() != DbNullType) { rec.SetValue(destIndex, value); } else { //we can't write to an auto number column so continue if (keepNulls && destIndex == idOrdinal) { continue; } if (keepNulls) { rec.SetValue(destIndex, DBNull.Value); } else { rec.SetDefault(destIndex); } } // Fire event if needed if (notifyAfter > 0 && rowCounter == notifyAfter) { FireRowsCopiedEvent(totalRows); rowCounter = 0; } } rowCounter++; totalRows++; rs.Insert(rec); } IdInsertOff(); } } //if we have our own transaction, we will commit it if (trans == null) { localTrans.Commit(CommitMode.Immediate); } }