c# - MongoDB - 无法在元素 {ParentProperty : is null} 中创建字段 'ChildProperty'

标签 c# mongodb mongodb-.net-driver mongodb-update

我有一个用户类:

public class User
{
    public Guid? Id { get; set; }
    public String? Name { get; set; }
    public Address? Address { get; set; }
}

和地址类别:

public class Address
{
    public String? Street { get; set; }
    public String? City { get; set; }
    public String? State { get; set; }
}

我正在尝试实现部分更新。这是动态完成的,但假设有人发送更新用户的城市和州,我这样做:

var filter = Builders<BsonDocument>.Filter.Eq("Id", id);
var updates = new List<UpdateDefinition<BsonDocument>>();
updates.Add(Builders<BsonDocument>.Update.Set("Address.City", "New City Value"));
updates.Add(Builders<BsonDocument>.Update.Set("Address.State", "New State Value"));
var update = Builders<BsonDocument>.Update.Combine(updates);
var bsonDocument = await collection.FindOneAndUpdateAsync(filter, update, new FindOneAndUpdateOptions<BsonDocument>
{
    ReturnDocument = ReturnDocument.After
});

这很有效,除非用户地址为null。在这种情况下,我收到错误:

MongoDB.Driver.MongoCommandException: Command findAndModify failed: Cannot create field 'City' in element {Address: null}.

是否有任何方法可以确保创建 Address 对象以便设置 City 和 State 属性?我想在不从数据库获取当前对象的情况下执行此操作。

最佳答案

认为您可以使用聚合管道更新来动态更新Address字段。

使用$cond运算符检查Address是否为null

如果是,则将整个对象设置为地址

如果否,请将当前Address 值与文档合并。

下面的查询可能看起来很复杂:

db.collection.update({
  Id: /* Id */
},
[
  {
    $set: {
      Address: {
        $cond: {
          if: {
            $eq: [
              "$Address",
              null
            ]
          },
          then: {
            "City": "New City Value",
            "State": "New State Value"
          },
          else: {
            $mergeObjects: [
              "$Address",
              {
                "City": "New City Value",
                "State": "New State Value"
              }
            ]
          }
        }
      }
    }
  }
])
var addressDocument = new BsonDocument
{
    { "City", "New City Value" },
    { "State", "New State Value" }
};

var update = Builders<BsonDocument>.Update.Pipeline(new PipelineStagePipelineDefinition<BsonDocument, BsonDocument>
(
    new PipelineStageDefinition<BsonDocument, BsonDocument>[]
    {
        new BsonDocument("$set", 
            new BsonDocument("Address", 
                new BsonDocument("$cond", 
                    new BsonDocument
                    {
                        { 
                            "if", 
                            new BsonDocument("$eq", 
                                BsonArray.Create(new object[] { "$Address", null })) 
                        },
                        {
                            "then",
                            addressDocument
                        },
                        {
                            "else",
                            new BsonDocument("$mergeObjects", 
                                BsonArray.Create(new object[] { "$Address", addressDocument }))
                        }
                    }
                )
            )
        )
    }
));

关于c# - MongoDB - 无法在元素 {ParentProperty : is null} 中创建字段 'ChildProperty',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73628953/

相关文章:

java - 找不到适合我类(class)的编解码器

mongodb - 我应该什么时候打开和关闭 MongoDB 连接?

C# 官方 MongoDB 驱动程序代码,用于更新(替换)MongoDB 文档中的内部数组

c# - 跨 .cake 文件共享全局变量

c# - 数据表作为 C# 控制台应用程序中的邮件

c# - 我如何编码一串 1 和 0 以进行传输?

node.js - 从 mongo 获取不同的坐标

c# - 如何仅将实体的已更改属性更新到 Entity Framework

mongodb在集合中查找不同的文档

c# - 使用 LINQ 和 MongoDb 重新创建位置数组运算符