mongodb - 构造 UpdateBuilder 时如何避免 'Duplicate Element Name' 错误

标签 mongodb mongodb-.net-driver

考虑下面的类

public class Something 
{
    public ObjectId Id;
    public DateTime DbUpdatedAt;
    public string AnotherProperty;
    public int SomeIntProp;
}

我通常会使用以下代码进行部分更新

var obj = ... // an instance of Something
var update = new UpdateBuilder<Something>();
update.Set(x => x.DbUpdatedAt, DateTime.UtcNow);
...
/// later on, 
// database is an instance of MongoDatabase
database.GetCollection("CollectionName")
        .Update(Query<Something>.Eq(x => x.Id, something.Id), update);

问题是,我不知道有什么方法可以检查 update 是否已配置为设置 DbUpdatedAt 的值。 如果我盲目地尝试为 DbUpdatedAt 设置新值,则会收到错误。

...
/// later on, 
update.Set(x => x.DbUpdatedAt, DateTime.UtcNow.AddHours(1)); // this throws a Duplicate element name error 
// database is an instance of MongoDatabase
database.GetCollection("CollectionName")
        .Update(Query<Something>.Eq(x => x.Id, something.Id), update);

我明白为什么会发生错误。我需要一种方法,

  1. 检测到存在重复的关键场景,
  2. 用新的键、值对替换旧的键、值对。

最佳答案

当前实现的 UpdateBuilder 认为尝试将同一字段设置为两个不同的值是一个错误(尽管我希望抛出的异常更清晰......)。

期望对同一字段调用 Set 两次只会用第二个字段覆盖第一个字段并不是没有道理的,但这不是它目前的工作方式。如果您认为应该这样做,请提交一份 JIRA 票证以建议更改。

作为解决方法,您可以在 UpdateBuilder 上定义一个按您希望的方式运行的扩展方法。它可能看起来像这样:

public static UpdateBuilder<TDocument> SetWithOverride<TDocument, TField>(this UpdateBuilder<TDocument> update, Expression<Func<TDocument, TField>> memberExpression, TField value)
{
    var set = Update<TDocument>.Set(memberExpression, value).ToBsonDocument();
    var combined = update.ToBsonDocument();
    if (combined.Contains("$set"))
    {
        var element = set[0].AsBsonDocument.GetElement(0);
        combined["$set"][element.Name] = element.Value;
    }
    else
    {
        combined.Merge(set);
    }
    return Update<TDocument>.Combine(combined.Elements.Select(e => new UpdateDocument(e)));
}

下面是一些示例代码,显示了它的使用情况:

var update = Update<C>.Set(c => c.X, 1).Set(c => c.Y, 2);
update = update.SetWithOverride(c => c.Y, 3);

关于mongodb - 构造 UpdateBuilder 时如何避免 'Duplicate Element Name' 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21227428/

相关文章:

MongoDB 和 Spark : difference between mongo-hadoop and mongo-spark

javascript - Mongoose 通过键获取最高值

c# - 使用 MongoDatabase 类而不是 MongoDatabaseImpl

c# - 无法使用 C# 驱动程序过滤 MongoDB 中的日期字段

mongodb - 使用 MongoDB Compass 连接

java - 如何从 mongodb 或 java 查询 prolog 中的文件

c# - 过滤mongodb数据

c# - 带有 setFields 和 AsQueryable 的 Mongodb c# 驱动程序 FindAll

mongodb - 使用官方 C# 驱动程序存储小文件时 MongoDb gridfs 中的 block 开销

node.js - 如何找到 Mongoose 查询中缺失的架构字段