public class Job
{
public Guid Id { get; set; }
public bool IsPending { get; set; }
public bool IsComplete { get; set; }
}
我有两个名为
List<Guid> A
和 List<Guid>B
的 Id 列表。
对于
List A
,我想设置Update.Set("IsPending", True)
和
对于
List B
,我想设置Update.Set("IsComplete", True)
。
我可以通过两次数据库调用来实现这一点:
this.UpdateManyAsync(Builders<Job>.Filter.In(f => f.Id, A), Builders<Job>.Update.Set(x => x.IsPending, true), cancellationToken: cancellationToken)
第二个调用为
this.UpdateManyAsync(Builders<Job>.Filter.In(f => f.Id, B), Builders<Job>.Update.Set(x => x.IsComplete, true), cancellationToken: cancellationToken)
是否可以在单个数据库调用中实现?
我认为不可能实现 Fluent Api,因为 MongoDB .NET 驱动程序不支持第二个参数为
Set
的 Expression
方法。这些是可用的方法:
public UpdateDefinition<TDocument> Set<TField>(FieldDefinition<TDocument, TField> field, TField value)
public UpdateDefinition<TDocument> Set<TField>(Expression<Func<TDocument, TField>> field, TField value)
为了实现您的要求,您可以使用聚合管道作为
BsonDocument[]
和 Builders<Job>.Update.Pipeline()
传递更新查询。
注意,在 MongoDB 文档中,我将 Guid 值存储为字符串类型,因此需要指定 Guid 序列化的映射规则,并将 Guid 转换为字符串才能使查询有效。
using MongoDB.Bson.Serialization.Serializers;
BsonClassMap.RegisterClassMap<Job>(
map =>
{
map.AutoMap();
map.MapProperty(x => x.Id).SetSerializer(new GuidSerializer(BsonType.String));
});
UpdateDefinition<Job> update = Builders<Job>.Update.Pipeline(new BsonDocument[]
{
new BsonDocument("$set",
new BsonDocument
{
{
"IsPending",
new BsonDocument("$cond",
new BsonDocument
{
{
"if",
new BsonDocument(
"$in",
new BsonArray
{
"$_id",
BsonArray.Create(A.Select(x => x.ToString()).ToList())
}
)
},
{ "then", true },
{ "else", "$IsPending" }
}
)
},
{
"IsComplete",
new BsonDocument("$cond",
new BsonDocument
{
{
"if",
new BsonDocument(
"$in",
new BsonArray
{
"$_id",
BsonArray.Create(B.Select(x => x.ToString()).ToList())
}
)
},
{ "then", true },
{ "else", "$IsComplete" }
}
)
}
}
)
});
演示