Подтвердить что ты не робот

Как найти findAll в новом mongo С# драйвере и сделать его синхронным

Я использовал официальный драйвер С# для создания FindAll и обновился до нового драйвера 2.0. FindAll устарел и заменен на Find. Я пытаюсь преобразовать простой метод, который возвращает мне список Class1. Не могу найти реалистичный пример, используя POCO в своей документации

var collection = database.GetCollection<ClassA>(Collection.MsgContentColName); return collection.FindAll().ToList();

Может кто-нибудь, пожалуйста, помогите мне конвертировать с 2.0-драйвером и вернуть список, а не задачу?

4b9b3361

Ответ 1

вы можете сделать это, чтобы добиться того же, что и с помощью драйвера 2.0,

var collection = database.GetCollection<ClassA>(Collection.MsgContentColName);
var doc = collection.Find(filter).ToListAsync();
doc.Wait();
return doc.Result;

Ответ 2

EDIT:

Они решили добавить обратно синхронную поддержку (хотя async все же предпочтительнее для операций ввода-вывода), поэтому вы можете просто использовать:

var list = collection.Find(_ => true).ToList();

Оригинал:

Не блокировать синхронно по асинхронному коду. Это плохо для производительности и может привести к взаимоблокировкам.

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

В новом драйвере v2.0 параметр async должен выглядеть следующим образом:

async Task FooAsync()
{
    var list = await collection.Find(_ => true).ToListAsync();
}

Ответ 3

С версией 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.

Ответ 4

Это с 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???
    }

Ответ 5

Чтобы получить все, вы можете использовать пустой фильтр в соответствии с документацией

FilterDefinition<T>.Empty

Например

    public async Task<IEnumerable<ClassA>> GetAllAsync() =>
                await database.GetCollection<ClassA>(Collection.MsgContentColName)
               .Find(FilterDefinition<ClassA>.Empty).ToListAsync();

Ответ 6

Это будет эквивалентно FindAll(),

var list = await collection.Find(new BsonDocument()).ToListAsync();