Как сделать findAll в новом драйвере mongo C# и сделать его синхронным
Я использовал официальный драйвер C#, чтобы сделать FindAll
и обновился до нового драйвера 2.0. FindAll
устарел и заменен на Find. Я пытаюсь преобразовать простой метод, который возвращает мне список Class1
. Не могу найти реалистичный пример использования POCO в своей документации
var collection = database.GetCollection<ClassA>(Collection.MsgContentColName);
return collection.FindAll().ToList();
Может кто-нибудь помочь мне преобразовать драйвер 2.0 и вернуть список, а не задачу?
5 ответов:
Вы можете сделать это, чтобы достичь того же с помощью драйвера 2.0,
var collection = database.GetCollection<ClassA>(Collection.MsgContentColName); var doc = collection.Find(filter).ToListAsync(); doc.Wait(); return doc.Result;
Правка:
Они решили добавить обратно синхронную поддержку (хотя асинхронность все еще предпочтительнее для операций ввода-вывода), так что вы можете просто использовать:
var list = collection.Find(_ => true).ToList();
Оригинал:
Не блокируйте синхронно асинхронный код. Это плохо сказывается на производительности и может привести к тупикам.
Если вы хотите сохранить синхронность приложения, рекомендуется использовать старый синхронный драйвер.
В новом драйвере v2.0 опция
async
должна выглядеть следующим образом это:async Task FooAsync() { var list = await collection.Find(_ => true).ToListAsync(); }
С MongoDb версии 2.2.4 реализация немного изменилась. Следуя рекомендациям, давайте построим соединение MongoDb следующим образом:
public static class PatientDb { public static IMongoCollection<Patient> Open() { var client = new MongoClient("mongodb://localhost"); var db = client.GetDatabase("PatientDb"); return db.GetCollection<Patient>("Patients"); } }
Теперь возвращается интерфейс
IMongoCollection
вместо экземпляра конкретного класса типаMongoCollection
. Больше нет необходимости создавать экземпляр сервера, чтобы получить базу данных, клиент может связаться с базой данных напрямую.Тогда в контроллере делается так:
public class PatientController : ApiController { private readonly IMongoCollection<Patient> _patients; public PatientController() { _patients = PatientDb.Open(); } public IEnumerable<Patient> Get() { return _patients.Find(new BsonDocument()).ToEnumerable(); } }
Где
_patients
- это IMongoCollection и to получить всех пациентов вместо того, чтобы использоватьFindAll()
теперь используетсяFind()
, где фильтр является новым экземпляромBsonDocument
.
Это с драйвером MongoDb C# 2.2
Новый драйвер C# является асинхронным. Нравится вам это или нет, но с этим надо разобраться. Он вступит в пригодится в будущем. Но пока.....
В коде ниже асинхронный вызов фактически делается синхронным из-за кода "результат.Помощью getawaiter().Метод getresult();". Это заставляет асинхронный код выполняться до завершения в обычном потоке.
static void MongoGoNow() { IMongoCollection<ClassA> collection = db.GetCollection<ClassA>(Collection.MsgContentColName); var result = TestFind(collection); result.GetAwaiter().GetResult(); //What's next??? } static async Task TestFind(IMongoCollection<ClassA> MyCollection) { var filter = new BsonDocument(); var count = 0; using (var cursor = await MyCollection.FindAsync(filter)) { while (await cursor.MoveNextAsync()) { var batch = cursor.Current; foreach (var document in batch) { // process document count++; } } }
Можно также объединить последние две строки кода в методе Main следующим образом: образом:
static void MongoGoNow() { IMongoCollection<ClassA> collection = db.GetCollection<ClassA>(Collection.MsgContentColName); TestFind(collection).GetAwaiter().GetResult(); //What's next??? }