Пустые значения записываются в базу данных в виде пустой строки вместо NULL
Я генерирую строки строк для вставки:
private StringReader MapWithHeaders(StreamReader reader, int clientId, HeadersMap dataHeadersMap, string delimiter, int uploadDataId, string dateFormat) { var lines = new HashSet<string?>(); var headers = new List<string>(); var i = 0; while (!reader.EndOfStream) { var line = reader.ReadLine(); var csvLineInOrder = ""; var values = line.Split(delimiter).Select(x => x.Trim(new[] { '/', '"' })).ToList(); if (i == 0) { headers = values.Select(x => x.Trim(new[] { '/', '"' })).ToList(); csvLineInOrder = String.Join(delimiter, DataHeaders); i++; } else { var campaignColumnNameId = headers.FindIndex(x => x.Equals(dataHeadersMap.CampaignColumnName)); var clusterColumnNameId = headers.FindIndex(x => x.Equals(dataHeadersMap.ClusterColumnName)); var userIdColumnNameId = headers.FindIndex(x => x.Equals(dataHeadersMap.UserIdColumnName)); var channelColumnNameId = headers.FindIndex(x => x.Equals(dataHeadersMap.ChannelColumnName)); csvLineInOrder = values[campaignColumnNameId] + delimiter + values[clusterColumnNameId] + delimiter + values[userIdColumnNameId] + delimiter + values[channelColumnNameId]; /* e.g.: ,,11111,,7,,674 */ } lines.Add(csvLineInOrder); } var stringCsv = string.Join("\n", lines); return new StringReader(stringCsv); }
затем я генерирую csvDataReader:
private async Task BulkImportCsvExtra(Stream file, int clientId, HeadersMap dataExtraHeadersMap, string delimiter, int uploadDataId, string dateFormat) { using (var reader = new StreamReader(file)) { var config = new CsvConfiguration(CultureInfo.InvariantCulture); config.BadDataFound = null; config.Delimiter = delimiter; // doesn't get triggered? config.TypeConverterCache.AddConverter<string>(new EmptyAsNullConverter()); var csvStreamReader = MapWithHeaders(reader, clientId, dataExtraHeadersMap, delimiter, uploadDataId, dateFormat); using (var csv = new CsvReader(csvStreamReader, config)) { var dataReader = new CsvDataReader(csv); // Need for header parsing csv.ReadHeader(); if (!HeadersValid(csv.Context.HeaderRecord, DataHeadersExtra)) throw new Exception(ExceptionCode.Import.InvalidHeaders); await _repository.BulkAdd(dataReader); } } }
и, наконец, использовать массовое копирование для добавления данных:
public async Task BulkAdd(IDataReader data) { if (Connection.State == ConnectionState.Broken || Connection.State == ConnectionState.Closed) { await Connection.OpenAsync(); } using (SqlBulkCopy bulk = new SqlBulkCopy(Connection)) { bulk.DestinationTableName = GetTableName(); bulk.BatchSize = BATCH_SIZE; bulk.BulkCopyTimeout = 0; // for infinity write 0 bulk.EnableStreaming = true; await bulk.WriteToServerAsync(data); } }
Что я уже пробовал:
однако пустые значения записываются как пустые строки, а не NULL, хотя у меня есть ограничения null по умолчанию на стороне базы данных. Я застрял здесь на целую вечность. есть идеи, как это исправить?
Я попробовал добавить нулевой конвертер:
public class EmptyAsNullConverter : CsvHelper.TypeConversion.StringConverter { public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData) { if (string.IsNullOrWhiteSpace(text)) return null; return text; } }
но он не используется даже тогда, когда я добавляю его в качестве конвертера типов, и я не знаю, как вызвать его/решить эту проблему