Как использовать десятичный тип в MongoDB

Как хранить десятичные знаки в MongoDB с помощью стандартного драйвера С#? Кажется, что все десятичные знаки хранятся в базе данных как строки.

Ответ 1

MongoDB неправильно поддерживает десятичные знаки до MongoDB v3.4. Перед этой версией он хранит десятичные числа в виде строк, чтобы избежать ошибок точности.

Pre v3.4 Храните десятичные знаки в виде строк, но это предотвращает арифметические операции. Операторы $min, $avg,... не будут доступны. Если точность не имеет большого значения, тогда вы можете переключиться на double.

v3.4 + Вы должны убедиться, что выполняются следующие предпосылки:

  • Сервер MongoDB должен быть не менее v3.4.
  • MongoCSharpDriver должен быть не менее v2.4.3.
  • В базе данных должно быть featureCompatibilityVersion установлено значение '3.4'. Если ваша база данных была создана более старой версией MongoDB, и вы обновили свой сервер до версии v3.4, ваша база данных все еще может быть в более старой версии.

Если у вас есть все установленные свойства, зарегистрируйте следующие сериализаторы, чтобы использовать тип decimal128:

BsonSerializer.RegisterSerializer(typeof(decimal), new DecimalSerializer(BsonType.Decimal128));
BsonSerializer.RegisterSerializer(typeof(decimal?), new NullableSerializer<decimal>(new DecimalSerializer(BsonType.Decimal128)));

Ответ 2

У меня возникли проблемы с использованием подхода RegisterSerializer, поскольку он жаловался, что у него уже зарегистрирован сериализатор, но альтернативой является создание собственного поставщика сериализации и его использование.

Здесь поставщик:

public class CustomSerializationProvider : IBsonSerializationProvider
{
    private static readonly DecimalSerializer DecimalSerializer = new DecimalSerializer(BsonType.Decimal128);
    private static readonly NullableSerializer<decimal> NullableSerializer = new NullableSerializer<decimal>(new DecimalSerializer(BsonType.Decimal128));

    public IBsonSerializer GetSerializer(Type type)
    {
        if (type == typeof(decimal)) return DecimalSerializer;
        if (type == typeof(decimal?)) return NullableSerializer;

        return null; // falls back to Mongo defaults
    }
}

который необходимо зарегистрировать, позвонив

BsonSerializer.RegisterSerializationProvider(new CustomSerializationProvider());

Ответ 3

Я недавно столкнулся с этой проблемой. Я решил это, просто пометив свой объект следующим образом:

[BsonRepresentation(BsonType.Decimal128)]
public decimal Price {get; set;}