如何使用UpdateManyAsync更新许多文档

时间:2018-07-05 14:50:37

标签: mongodb mongodb-query mongodb-.net-driver

我有以下方法来更新MongoDB中的文档:

public async Task UpdateAsync(T entity)
{
    await _collection.ReplaceOneAsync(filter => filter.Id == entity.Id, entity);
}

哪个工作正常-我只是想知道是否有人举了UpdateManyAsync函数如何工作的示例:

public async Task UpdateManyAsync(IEnumerable<T> entities)
{
    await _collection.UpdateManyAsync(); // What are the parameters here
}

任何建议都值得赞赏!

2 个答案:

答案 0 :(得分:1)

UpdateOneAsync的工作方式与Mongo shell中updatemulti: true的工作方式相同。因此,您可以指定过滤条件和更新操作,它将影响多个文档。例如,要增加a大于a的所有10字段,可以使用以下方法:

var builder = Builders<SampleClass>.Update;
await myCollection.UpdateManyAsync(x => x.a > 10, builder.Inc(x => x.a, 1));

我想您想替换多个文档。可以使用bulkWrite方法来实现。如果您需要C#中的通用方法,则可以引入某种标记器接口来构建替换操作的过滤器部分:

public interface IMongoIdentity
{
    ObjectId Id { get; set; }
}

然后,您可以将通用约束添加到类中,并在.NET中使用BuikWrite,如下所示:

class YourRepository<T> where T : IMongoIdentity
{
    IMongoCollection<T> collection;

    public async Task UpdateManyAsync(IEnumerable<T> entities)
    {
        var updates = new List<WriteModel<T>>();
        var filterBuilder = Builders<T>.Filter;

        foreach (var doc in entities)
        {
            var filter = filterBuilder.Where(x => x.Id == doc.Id);
            updates.Add(new ReplaceOneModel<T>(filter, doc));
        }

        await collection.BulkWriteAsync(updates);
    }
}

答案 1 :(得分:0)

作为@mickl答案,您不能使用x => x.Id,因为它是泛型 用途如下:

public async Task<string> UpdateManyAsync(IEnumerable<T> entities)
{ 
     var updates = new List<WriteModel<T>>();
     var filterBuilder = Builders<T>.Filter;

     foreach (var doc in entities)
     {
          foreach (PropertyInfo prop in typeof(T).GetProperties())
          {
              if (prop.Name == "Id")
              {
                  var filter = filterBuilder.Eq(prop.Name, prop.GetValue(doc));
                  updates.Add(new ReplaceOneModel<T>(filter, doc));
                  break;
              }
          }
     }
     BulkWriteResult result = await _collection.BulkWriteAsync(updates);
     return result.ModifiedCount.ToString();
}