使用 MongoDB C# 驱动程序 (2.0) 您如何指定和 UpdateDefinition 将忽略具有空值的属性

Using the MongoDB C# Driver (2.0) how might you specify and UpdateDefinition that will ignore properties with null values

Contact poco 有 5 个属性 - Id、FirstName、LastName、Phone、Email。 Phone 和 Email 最初为空,客户端未引用它们 - 它们在 poco 中供 "future" 使用。 UpdateDefinition 为每个 属性 指定 .Set 构造,但这样做会向文档添加 Email 和 Phone,即使它们为空 - 我们如何避免这种情况?

看来这不可能。我们不得不问作者,但看起来这是一个深思熟虑的选择,我相信这是有道理的。即使您在字段上使用 [BsonIgnoreIfNull][BsonIgnoreIfDefault],明确的 Set() 仍将或多或少直接转换为 $setSet() method is a very thin wrapper 将创建一个 BsonDocument 然后发送到服务器。

问题是,如果这不同,则意味着使用 Set 和值 null 转换为 $unset这看起来真的很奇怪而且违反直觉。

关键问题似乎是大量显式原子操作的使用 - 为什么不简单地替换 文档?在文档数据库中,这是最直接的方法,并且 $set 只有当您对一个对象有不同的编写者并且您只想有选择地更新一个或两个字段时才有意义,或者如果文档看起来太大而无法通过管道传输来回如此,再次有选择地,您只想更新几个字段。在整个对象上使用 $set 对我来说似乎毫无用处。如果您有 SQL 背景,请记住查询语言是完全不同的,因为 SQL 没有 替换操作,它总是使用显式设置语句.

编辑:要在嵌入式数组中解决这个问题,$ 位置更新运算符可以解决问题,因此您可以 $set 整个嵌入文档:

db.customers.update(
   { "contacts.id" : contactIdToReplace },
   { $set: { "contacts.$" : { "email" : "foo", ... } } }
)

在 C# 中,这转换为

collection.UpdateOneAsync(
  Builders<Customer>.Filter.Eq("Contacts.Id", contact.Id), 
  Builders<Customer>.Update.Set("Contacts.$", 
     new Contact { Email = null })).Wait();

Email 属性 在 Contact 上使用 [BsonIgnoreIfNull],这将按预期工作。