Ответ 1
вы можете сделать это, чтобы добиться того же, что и с помощью драйвера 2.0,
var collection = database.GetCollection<ClassA>(Collection.MsgContentColName);
var doc = collection.Find(filter).ToListAsync();
doc.Wait();
return doc.Result;
Я использовал официальный драйвер С# для создания FindAll
и обновился до нового драйвера 2.0. FindAll
устарел и заменен на Find. Я пытаюсь преобразовать простой метод, который возвращает мне список Class1
. Не могу найти реалистичный пример, используя POCO в своей документации
var collection = database.GetCollection<ClassA>(Collection.MsgContentColName);
return collection.FindAll().ToList();
Может кто-нибудь, пожалуйста, помогите мне конвертировать с 2.0-драйвером и вернуть список, а не задачу?
вы можете сделать это, чтобы добиться того же, что и с помощью драйвера 2.0,
var collection = database.GetCollection<ClassA>(Collection.MsgContentColName);
var doc = collection.Find(filter).ToListAsync();
doc.Wait();
return doc.Result;
EDIT:
Они решили добавить обратно синхронную поддержку (хотя async все же предпочтительнее для операций ввода-вывода), поэтому вы можете просто использовать:
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 и для извлечения всех пациентов вместо использования FindAll()
теперь используется Find()
, где фильтр является новым экземпляром BsonDocument
.
Это с MongoDb С# Driver 2.2
Новый драйвер С# является асинхронным. Нравится это или нет, с этим нужно бороться. Это пригодится в будущем. Но сейчас...
В приведенном ниже коде асинхронный вызов эффективно выполняется синхронно из-за кода "result.GetAwaiter(). GetResult();". Это приводит к завершению выполнения асинхронного кода в нормальном потоке.
static void MongoGoNow()
{
IMongoCollection<ClassA> collection = db.GetCollection<ClassA>(Collection.MsgContentColName);
var result = TestFind(collection);
result.GetAwaiter().GetResult();
//What 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 next???
}
Чтобы получить все, вы можете использовать пустой фильтр в соответствии с документацией
FilterDefinition<T>.Empty
Например
public async Task<IEnumerable<ClassA>> GetAllAsync() =>
await database.GetCollection<ClassA>(Collection.MsgContentColName)
.Find(FilterDefinition<ClassA>.Empty).ToListAsync();
Это будет эквивалентно FindAll(),
var list = await collection.Find(new BsonDocument()).ToListAsync();