Mongodb C#驱动程序在数组为空时更新所有子数组元素失败

时间:2019-12-17 14:23:31

标签: c# mongodb

链接到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"
        }
    }
}

并且由于解析,读取操作失败。 进行更新时,我遇到以下问题:

  

写操作导致错误。 “报价”路径必须存在   在文档中以应用数组更新。

1 个答案:

答案 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();
        }
    }
}