web-dev-qa-db-ja.com

新しいmongo C#ドライバーでfindAllを実行して同期させる方法

公式のC#ドライバーを使用してFindAllを実行し、新しいドライバー2.0にアップグレードしました。 FindAllは廃止され、Findに置き換えられました。 _Class1_のリストを返す単純なメソッドを変換しようとしています。カントは、ドキュメントでPOCOを使用して現実的な例を見つけます

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

誰かが2.0ドライバーで変換して、タスクではなくリストを返すのを手伝ってもらえますか?

22
Kar

編集:

彼らは同期サポートを追加することを決定しました(ただし、IO操作には非同期がまだ望ましいのですが)

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

元の:

非同期コードで同期的にブロックしないでください。パフォーマンスに悪影響を及ぼし、デッドロックにつながる可能性があります。

アプリケーションの同期を維持する場合は、古い同期ドライバーを使用し続けることをお勧めします。

新しいv2.0ドライバーでは、asyncオプションは次のようになります。

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

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の新しいインスタンスです。

2
PedroSouki

すべてを取得するには、 documentation に従ってempty filterを使用できます

FilterDefinition<T>.Empty

例えば

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

これは、MongoDb C#Driver 2.2を使用している

新しいC#ドライバーは非同期です。好むと好まざるとにかかわらず、対処する必要があります。これは将来便利になります。しかし、今のところ...

以下のコードでは、コード "result.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メソッドの最後の2行のコードをマージすることもできます。

    static void MongoGoNow()
    {
        IMongoCollection<ClassA> collection = db.GetCollection<ClassA>(Collection.MsgContentColName);
        TestFind(collection).GetAwaiter().GetResult();
        //What's next???
    }
1
Brett Jones

これはFindAll()と同等です。

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