链接到this post,我尝试并能够更新文档的所有子数组元素。总结一下,我想在C#中使用$[]运算符
这是我的存储库中的更新请求:
var date = DateTime.UtcNow;
update = update.Set(x => x.LastUpdateDate, date);
update = update.Set(x => x.EndDate, date);
update = update.Set("Quotes.$[].DraftStatus", Constants.ProjectCloseStatus);
var res = _mongoCollection.UpdateMany(filter, update);
当“ Quotes”数组不为空时,它工作得很好。 不幸的是,当数组不存在时,我在数据库中得到以下输出:
{
"_id" : ObjectId("5df73ac41043a04ee0873253"),
"Quotes" : {
"$[]" : {
"DraftStatus" : "CLOSE"
}
}
}
并且由于解析,读取操作失败。 进行更新时,我遇到以下问题:
写操作导致错误。 “报价”路径必须存在 在文档中以应用数组更新。
答案 0 :(得分:0)
仅允许您在作为数组的字段上运行数组更新操作。如果该字段的值为null
或不存在,则更新也将失败。
最简单的解决方案是在保存文档时使该字段成为空数组,使其在db中看起来像这样:
{
"_id": ObjectId("5df9af0e22bb051d0c25c936"),
"Quotes": [ ]
}
可以通过为您的c#属性设置默认值来轻松实现,例如:
public Quote[] Quotes { get; set; } = new Quote[0];
测试程序:
using MongoDB.Entities;
using MongoDB.Entities.Core;
namespace StackOverflow
{
public class Test : Entity
{
public string Name { get; set; }
public Quote[] Quotes { get; set; } = new Quote[0];
}
public class Quote
{
public bool flag { get; set; }
public string status { get; set; }
}
public class Program
{
private static void Main(string[] args)
{
new DB("test", "localhost");
(new[] {
new Test { Name = "no quotes"},
new Test { Quotes = new[]{
new Quote { flag = true, status = "PROCESSED" } } },
new Test { Quotes = new[]{
new Quote { flag = true, status = "NOT-PROCESSED" },
new Quote { flag = true, status = "NOT-PROCESSED" }
}}
}).Save();
var field = Prop.PosAll<Test>(t => t.Quotes[0].flag);
DB.Update<Test>()
.Match(_ => true)
.Modify(b => b.Set(field, false))
.Execute();
}
}
}