MongoDB C#驱动程序:如果不存在则创建文档

时间:2017-09-07 08:26:29

标签: c# mongodb

我有一些类型为User的POCO,我有些担心其属性将来会发生变化。我有一个带有Users集合的mongodb来存储数据。它没有唯一性限制,我不能创造一个不幸的。我的应用程序从第三方存档源导入了一堆旧用户,我希望能够将这些用户写入mongo,但我不想要重复项,我不想在匹配时替换用户数据因为mongo中的数据是实际的。基本上我们可以通过匹配过滤器来定义用户副本,例如a.Username == b.Username && a.Email == b.Email或类似的东西,我不希望它与这个问题相关,我们只是说那里我们可以告诉我们的方式如果用户A和B相同。

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

有没有办法绕过这个问题?也许通过使用reflecion和PropertyInfo或直接与BsonDocument合作?或者也许我错过了一些东西并且有更简单的方法吗?提前谢谢。

1 个答案:

答案 0 :(得分:2)

好的,毕竟不是那么难:

    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);