繁体   English   中英

使用MongoDB .Net驱动程序查找POCO

[英]Find POCO with MongoDB .Net driver

MongoDB比我想起来要难! 我尝试了具有各种功能和选项的if-exists-replace-else-insert的各种版本。 应该很容易,不是吗?

我个人认为以下方法应该有效。

var collection = storageClient.GetCollection<Observer>("observers");
await collection.Indexes.CreateOneAsync(Builders<Observer>.IndexKeys.Ascending(_ => _.MyId), new CreateIndexOptions { Unique = true });

foreach (var observer in _observers)
{
     observer.Timestamp = DateTime.Now;

     var res = await collection.FindAsync(o => o.MyId == observer.MyId);
     if (res==null ||res.Current == null) {
         await collection.InsertOneAsync(observer); //Part 1, fails 2nd time solved with res.MoveNextAsync()
     } 
     else
     {
            observer.ID = res.Current.Single().ID;
            var res2 = await collection.ReplaceOneAsync(o=>o.MyId==observer.MyId, observer);

            var res3 = await collection.FindAsync(o => o.MyId == observer.MyId);
            await res3.MoveNextAsync();
            Debug.Assert(res3.Current.Single().Timestamp == observer.Timestamp); //Part 2, Assert fails.
     }
}

观察者大致如下所示:

public class Observer : IObserver
{
    [BsonId]
    public Guid ID { get; set; }

    public int MyId { get; set; }

    public DateTime Timestamp { get; set; }
}

我第二次使用完全相同的集合运行它时,我意外地得到:

E11000 duplicate key error index: db.observers.$MyId_1  dup key: { : 14040 }

编辑:

添加了原始的第二部分代码:替换。

编辑2:

现在我的代码看起来像这样。 仍然失败。

var collection = storageClient.GetCollection<Observer>("gavagai_mentions");
    await collection.Indexes.CreateOneAsync(Builders<Observer>.IndexKeys.Ascending(_ => _.MyID), new CreateIndexOptions { Unique = true });
    foreach (var observer in _observers)
    {
    observer.Timestamp = DateTime.Now;

    // Create a BsonDocument version of the POCO that we can manipulate
    // and then remove the _id field so it can be used in a $set.
    var bsonObserver = observer.ToBsonDocument();
    bsonObserver.Remove("_id");

    // Create an update object that sets all fields on an insert, and everthing
    // but the immutable _id on an update.
    var update = new BsonDocument("$set", bsonObserver);
    update.Add(new BsonDocument("$setOnInsert", new BsonDocument("_id", observer.ID)));

    // Enable the upsert option to create the doc if it's not found.
    var options = new UpdateOptions { IsUpsert = true };
    var res = await collection.UpdateOneAsync(o => o.MyID == observer.MyID,
                          update, options);


    var res2 = await collection.FindAsync(o => o.MyID == observer.MyID);
    await res2.MoveNextAsync();
    Debug.Assert(res2.Current.Single().Timestamp == observer.Timestamp); //Assert fails, but only because MongoDB stores dates as UTC, or so I deduce. It works!!
    }

如果尚不存在该文档,则可以使用IsUpsert选项使用IsUpsert原子地进行UpdateOneAsync

foreach (var observer in _observers)
{
    // Create a BsonDocument version of the POCO that we can manipulate
    // and then remove the _id field so it can be used in a $set.
    var bsonObserver = observer.ToBsonDocument();
    bsonObserver.Remove("_id");

    // Create an update object that sets all fields on an insert, and everthing
    // but the immutable _id on an update.
    var update = new BsonDocument("$set", bsonObserver);
    update.Add(new BsonDocument("$setOnInsert", new BsonDocument("_id", observer.ID)));

    // Enable the upsert option to create the doc if it's not found.
    var options = new UpdateOptions { IsUpsert = true };    
    var res = await collection.UpdateOneAsync(o => o.MyId == observer.MyId,
                                              update, options);
}

好的,距离我使用游标已经很长时间了。

await res.MoveNextAsync();

帮助。

对于Google来说,这东西并不难,但事实是,我失败了,所以我将不再赘述。

如果您对第二部分有一个答案https://stackoverflow.com/questions/32586064/replace-poco-with-mongodb-net-driver-2 ,然后真的要在这里发布,那么我会很高兴两个编辑问题。

正如评论中指出的那样,该信息实际上可以在文档http://mongodb.github.io/mongo-csharp-driver/2.0/reference/driver/crud/reading/#finding-documents中获得

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM