c# - MongoDB C# 驱动程序 : create document if not exists

标签 c# mongodb

我有一些 User 类型的 POCO我担心它的属性将来会发生变化。我有一个 Users 的 mongodb集合来存储数据。它没有唯一性约束,不幸的是我无法创建一个。我的应用程序从第 3 方存档源导入了一堆旧用户,我希望能够将这些用户写入 mongo,但我不想要重复项,也不想替换匹配的用户数据,因为 mongo 中的数据是实际的。基本上我们可以通过匹配像 a.Username == b.Username && a.Email == b.Email 这样的过滤器来定义用户副本。或类似的东西,我不希望它与这个问题相关,我们只是说有一种方法可以判断用户 A 和 B 是否相同。

所以我在这里唯一的选择似乎是使用带有 SetOnInsert 的 upsert Update。在 C# 驱动程序中有一个方法 Builders<User>.Update.SetOnInsert<TField>(Expression<User,TField>, TField)但我将不得不多次调用它来枚举所有属性。如果这些属性将来会发生变化,则必须有人更新此方法,我不喜欢它。

有没有办法绕过这个问题?也许通过使用反射和 PropertyInfo或使用 BsonDocument直接地?或者也许我遗漏了一些东西并且有更简单的方法来做到这一点?提前致谢。

最佳答案

好吧,毕竟没那么难:

    var updates = new List<WriteModel<User>>();
    foreach (User appUser in users)
    {
        FilterDefinition<User> filter = Builders<User>.Filter.Eq(x => x.Username, appUser.Username) & ...

        var bsonDoc = appUser.ToBsonDocument();
        UpdateDefinition<User> updateDefinition = new UpdateDefinitionBuilder<User>().Unset("______"); // HACK: I found no other way to create an empty update definition
        foreach (var element in bsonDoc.Elements)
        {
            if (element.Name == "_id" || element.Value == BsonNull.Value)
                continue;
            updateDefinition = updateDefinition.SetOnInsert(element.Name, element.Value);
        }
        UpdateOneModel<User> update = new UpdateOneModel<User>(filter, updateDefinition) { IsUpsert = true };
        updates.Add(update);
    }
    MongoConnectionHelper.Database.GetCollection<User>("Users").BulkWrite(updates);

关于c# - MongoDB C# 驱动程序 : create document if not exists,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46091483/

相关文章:

c# - Enumerable.Repeat with Union and Take 不返回 'Take' 值

c# - 如何使用非交互式身份验证连接到 Power BI API?

c# - System.Core 未添加到对程序集的引用

javascript - Mongoose 批量更新操作

arrays - 输出mongoose中的所有文档

c# - 有没有办法使用 Vector3 制作 switch/case?

java - mongo jpa 查询之间

mongodb - "group by"对 meteor 收集的查询

javascript - 发出 GET 请求时 Node 路由不起作用

c# - AOP 与元编程