Mongo Builder использует `String` для поля класса` DateTime` - PullRequest
0 голосов
/ 30 августа 2018

У меня есть класс с полем типа DateTime:

class Model {
    public DateTime Date { get; set; }
}

В базе данных Монго она хранится как:

"Date" : "2018-02-01T13:22:08Z"

Код:

var builder = Builders<Model>.Filter;

var filter = builder.In("Date", new[]
            {
               "2018-02-01T13:22:08Z"
            });

// Returns zero element list
_collection.Find(filter).ToList();

Интересная вещь:

  var workingFilter = new BsonDocument()
        {
            { "Date", "2018-02-01T13:22:08Z"}
        };

// This one actually works
_collection.Find(workingFilter).ToList();

Я думаю, что-то не так с утилитой Builder Монго, когда я предоставляю поле string в качестве значения DateTime для запроса.

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

Прежде всего, ваш .NET DateTime хранится как MongoDB string, что не является поведением по умолчанию. По умолчанию вы должны видеть что-то подобное в вашей базе данных:

"Date" : ISODate("2018-02-01T13:22:08Z")

Таким образом, существует несоответствие между типом, хранящимся в вашей базе данных, и типом, который есть в вашей модели. Имейте в виду, что MongoDB проверяет типы перед значениями, и не существует неявного приведения типа JavaScript.

В вашем рабочем примере вы использовали BsonDocument, который обрабатывает динамические документы , поэтому драйвер просто игнорировал тип данных, указанный в вашей модели, и он переводился в

db.yourCollection.find({"Date" : "2018-02-01T13:22:08Z"})

и возвращает этот документ.

Второй фрагмент кода использует универсальный Filter Builder, поэтому вы указали, что заботитесь о типах в Model классе.

Вы можете включить профилировщик MongoDB на уровне 2, а затем запустить свой код .NET:

db.setProfilingLevel(2)

Затем вы можете выполнить следующий запрос в вашей базе данных:

db.system.profile.find({ns: "yourdb.yourcollection"}).sort({ts:-1}).limit(1).pretty()

и вы увидите запрос, сгенерированный драйвером:

"command" : {
            "find" : "yourcollection",
            "filter" : {
                    "Date" : {
                            "$in" : [
                                    ISODate("2018-02-01T13:22:08Z")
                            ]
                    }
            },
            "$db" : "yourdb"
    }

Итак, как вы можете видеть, драйвер знает о DateTime и преобразует вашу строку в ISODate, что вызывает несоответствие типов на уровне запросов к базе данных, и поэтому вы не получаете результатов.

Решения? Либо сохраните ваш .NET DateTime как ISODate в MongoDB (рекомендуется), либо всегда используйте BsonDocument для построения ваших запросов.

0 голосов
/ 30 августа 2018

Используйте BsonDateTime вместо DateTime в вашем C #. Если вы хотите предоставить .NET DateTime своим пользователям C # и по-прежнему сохранять дату как дату в Mongo, создайте два свойства, которые получают / устанавливают для одного и того же резервного хранилища, и используйте некоторые атрибуты Mongo, чтобы не сохранять собственный DateTime и переименуйте BsonDateTime.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...