Получать коллекции MongoDB как последовательность IMongoCollection <T>в драйвере .NET - PullRequest
1 голос
/ 12 марта 2019

IMongoDatabase.ListCollections вернуть курсор над BsonDocument. Почему он не возвращает курсор над IMongoCollection<T> вместо этого?

Я пытался написать общий GetCollection метод для извлечения коллекции по типу документа, что-то вроде этого:

private IMongoCollection<T> GetCollection<T>()
{
    var client = new MongoClient("connectionString");
    var db = client.GetDatabase("dbName");
    var coll = db.ListCollectionsAsync().Result.ToListAsync().Result
        // Find collection of document of type T
        // Collection is a BsonDocument instead
        .Find(collection => typeof(collection) == typeof(T));

    return coll;
}

Ответы [ 2 ]

0 голосов
/ 12 марта 2019

Коллекции MongoDB имеют гибкую схему, которая позволяет вставлять в коллекцию любой документ с любой структурой. Например, мы можем вставить следующие 3 объекта в коллекцию test, и она действительна:

> db.test.insertMany([{one: 1}, {two:2}, {three: 3}])
{
        "acknowledged" : true,
        "insertedIds" : [
                ObjectId("5c87c954ed372bf469367e57"),
                ObjectId("5c87c954ed372bf469367e58"),
                ObjectId("5c87c954ed372bf469367e59")
        ]
}
> db.test.find().pretty()
{ "_id" : ObjectId("5c87c954ed372bf469367e57"), "one" : 1 }
{ "_id" : ObjectId("5c87c954ed372bf469367e58"), "two" : 2 }
{ "_id" : ObjectId("5c87c954ed372bf469367e59"), "three" : 3 }

Таким образом, вы не можете сопоставить коллекцию MongoDB с типом .NET, так как коллекция не знает тип.

0 голосов
/ 12 марта 2019

Драйвер не знает, какой документ находится в коллекции, поэтому он принимает параметр типа T.Сам MongoDB не знает, как документы в базе данных соответствуют типам в вашем приложении.

Невозможно подключиться к «универсальному» развертыванию MongoDB и просто обнаружить коллекции и типы вих.Это код, который вам нужно написать, и, вероятно, он не сработает, так как это будет что-то вроде проб и ошибок.

Если вы просто пытаетесь создать фабричный тип, вам нужно будетсоздайте вспомогательный список коллекций перед вызовом GetCollection<T>.

Вы можете попробовать использовать имя типа в качестве имени коллекции.Это сделает имя коллекции повторяемым (если имя типа не изменено).Но я никогда не проверял его, и у него могут быть некоторые отличительные черты в реальном мире.

public class MyDatabase
{
    private readonly IMongoClient _client;
    public MyDatabase(string connectionString)
    {
        _client = new MongoClient(connectionString);
    }

    public IMongoCollection<T> GetCollection<T>()
    {
        var db = _client.GetDatabase("dbName");
        return db.GetCollection<T>(typeof(T).Name);
    }
}

Если вы предпочитаете, чтобы имена коллекций были во множественном числе, то вам может помочь что-то вроде Humanizer .

Я обычно предпочитаю создавать тип, у которого коллекции являются полями в классе.Например:

public class MyDatabase
{
    private readonly IMongoClient _client;
    public IMongoCollection<Foo> Foos { get; }
    public IMongoCollection<Bar> Bars { get; }
    public MyDatabase(string connectionString)
    {
        _client = new MongoClient(connectionString);
        var db = _client.GetDatabase("myDb");
        Foos = db.GetCollection<Foo>("foos");
        Bars = db.GetCollection<Bar>("bars");
    }
}
...