mongodb 如何使用UpdateManyAsync更新多个文档

pbossiut  于 2023-02-11  发布在  Go
关注(0)|答案(3)|浏览(240)

我使用以下方法更新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
}

任何建议都是赞赏!

w6mmgewl

w6mmgewl1#

UpdateManyAsyncupdate在Mongo shell中的工作方式相同。因此,您可以指定过滤条件和更新操作,它将影响多个文档。例如,要递增所有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; }
}

然后,您可以向类中添加泛型constain,并在.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);
    }
}
rqmkfv5c

rqmkfv5c2#

正如@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();
}
vc9ivgsu

vc9ivgsu3#

或者按照Bson属性:

public async Task UpdateManyAsync(IEnumerable<TEntity> objs, CancellationToken cancellationToken = default) 
{
var updates = new List<WriteModel<TEntity>>();
var filterBuilder = Builders<TEntity>.Filter;

foreach (var obj in objs)
{
    foreach (var prop in typeof(TEntity).GetProperties())
    {
        object[] attrs = prop.GetCustomAttributes(true);
        foreach (object attr in attrs)
        {
            var bsonId = attr as BsonIdAttribute;
            if (bsonId != null)
            {
                var filter = filterBuilder.Eq(prop.Name, prop.GetValue(obj));
                updates.Add(new ReplaceOneModel<TEntity>(filter, obj));
                break;
            }
        }
    }
}

await _dbCollection.BulkWriteAsync(updates, null, cancellationToken);

}

相关问题