net - Cómo hacer findAll en el nuevo controlador mongo C#y hacerlo sincrónico
mongodb driver php (5)
Estaba usando el controlador oficial de C # para hacer un FindAll
y actualicé al nuevo controlador 2.0. FindAll
está obsoleto y se reemplaza con Find. Estoy tratando de convertir un método simple que me devuelve una lista de Class1
. No puedo encontrar un ejemplo realista utilizando un POCO en su documentación
var collection = database.GetCollection<ClassA>(Collection.MsgContentColName); return collection.FindAll().ToList();
¿Puede alguien ayudarme a convertir con el controlador 2.0 y devolver una lista y no una tarea?
Con la versión 2.2.4 de MongoDb, la implementación cambió un poco. Siguiendo las mejores prácticas, construyamos la conexión de MongoDb de esta manera:
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");
}
}
Ahora se devuelve una interfaz de IMongoCollection
lugar de una instancia de una clase concreta como MongoCollection
. No es necesario crear una instancia de servidor para obtener más la base de datos, el cliente puede acceder a la base de datos directamente.
Luego en el controlador se hace así:
public class PatientController : ApiController
{
private readonly IMongoCollection<Patient> _patients;
public PatientController()
{
_patients = PatientDb.Open();
}
public IEnumerable<Patient> Get()
{
return _patients.Find(new BsonDocument()).ToEnumerable();
}
}
Donde _patients
es un IMongoCollection y para recuperar a todos los pacientes en lugar de usar FindAll()
ahora se usa Find()
donde el filtro es una nueva instancia de BsonDocument
.
EDITAR:
Decidieron volver a agregar soporte síncrono (aunque async aún es preferible para las operaciones de E / S), por lo que simplemente puede usar:
var list = collection.Find(_ => true).ToList();
Original:
No bloquee sincrónicamente en código asíncrono. Es malo para el rendimiento y podría llevar a puntos muertos.
Si desea mantener su aplicación sincrónica, se recomienda que siga utilizando el controlador síncrono anterior.
En el nuevo controlador v2.0, la opción async
debería tener este aspecto:
async Task FooAsync()
{
var list = await collection.Find(_ => true).ToListAsync();
}
Esto es con MongoDb C # Driver 2.2
El nuevo controlador de C # es asíncrono. Guste o no debe ser tratado. Será útil en el futuro. Pero por ahora...
En el código siguiente, la llamada asíncrona se realiza de manera síncrona debido al código "result.GetAwaiter (). GetResult ();". Esto hace que el código asíncrono se ejecute hasta su finalidad en el flujo normal.
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++;
}
}
}
También puede combinar las dos últimas líneas de código en el método Principal de la siguiente manera:
static void MongoGoNow()
{
IMongoCollection<ClassA> collection = db.GetCollection<ClassA>(Collection.MsgContentColName);
TestFind(collection).GetAwaiter().GetResult();
//What''s next???
}
Para recuperar todo, puede usar un filtro vacío según la documentation
FilterDefinition<T>.Empty
Por ejemplo
public async Task<IEnumerable<ClassA>> GetAllAsync() =>
await database.GetCollection<ClassA>(Collection.MsgContentColName)
.Find(FilterDefinition<ClassA>.Empty).ToListAsync();
puedes hacer esto para lograr lo mismo usando el driver 2.0,
var collection = database.GetCollection<ClassA>(Collection.MsgContentColName);
var doc = collection.Find(filter).ToListAsync();
doc.Wait();
return doc.Result;