我有一些User类型的POCO,我担心它的属性在未来会发生变化。我有一个带有Users集合的mongodb来存储数据。它没有唯一性约束,不幸的是我不能创建一个。我的应用程序从第三方档案源导入了一堆老用户,我希望能够将这些用户写入mongo,但我不想要重复的用户数据,我也不想替换match上的用户数据,因为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?或者我错过了什么,有更简单的方法吗?提前谢谢。
发布于 2017-09-07 18:24:56
好的,毕竟这并不难:
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);https://stackoverflow.com/questions/46091483
复制相似问题