CommandParameterValues GetDocumentParameters(Func <DocumentMap, string> allocateId, object customAssignedId, CustomIdAssignmentBehavior?customIdAssignmentBehavior, object document, DocumentMap mapping, string prefix = null) { var id = mapping.IdColumn.PropertyHandler.Read(document); if (customIdAssignmentBehavior == CustomIdAssignmentBehavior.ThrowIfIdAlreadySetToDifferentValue && customAssignedId != null && id != null && customAssignedId != id) { throw new ArgumentException("Do not pass a different Id when one is already set on the document"); } if (mapping.IdColumn.Type == typeof(string) && string.IsNullOrWhiteSpace((string)id)) { id = string.IsNullOrWhiteSpace(customAssignedId as string) ? allocateId(mapping) : customAssignedId; mapping.IdColumn.PropertyHandler.Write(document, id); } var result = new CommandParameterValues { [$"{prefix}{mapping.IdColumn.ColumnName}"] = id }; switch (mapping.JsonStorageFormat) { case JsonStorageFormat.TextOnly: result[$"{prefix}{JsonVariableName}"] = serializer.SerializeText(document, mapping); break; case JsonStorageFormat.CompressedOnly: result[$"{prefix}{JsonBlobVariableName}"] = serializer.SerializeCompressed(document, mapping); break; case JsonStorageFormat.MixedPreferCompressed: result[$"{prefix}{JsonBlobVariableName}"] = serializer.SerializeCompressed(document, mapping); result[$"{prefix}{JsonVariableName}"] = null; break; case JsonStorageFormat.MixedPreferText: result[$"{prefix}{JsonVariableName}"] = serializer.SerializeText(document, mapping); result[$"{prefix}{JsonBlobVariableName}"] = null; break; case JsonStorageFormat.NoJson: // Nothing to serialize break; default: throw new ArgumentOutOfRangeException(); } foreach (var c in mapping.WritableIndexedColumns()) { var value = c.PropertyHandler.Read(document); if (value != null && value != DBNull.Value && value is string && c.MaxLength != null && c.MaxLength.Value > 0) { var attemptedLength = ((string)value).Length; if (attemptedLength > c.MaxLength) { throw new StringTooLongException($"An attempt was made to store {attemptedLength} characters in the {mapping.TableName}.{c.ColumnName} column, which only allows {c.MaxLength} characters."); } } else if (value != null && value != DBNull.Value && value is DateTime && value.Equals(DateTime.MinValue)) { value = SqlDateTime.MinValue.Value; } result[$"{prefix}{c.ColumnName}"] = value; } return(result); }