I have some POCO of a type User
and I have some concerns its properties going to change in future. I have a mongodb with Users
collection to store the data. There's no uniqueness constraint on it, and I can't create one unfortunatelly. My app imports a bunch of old users from 3rd party archive source and I want to be able to write these users into mongo, but I don't want the duplicates and I don't want to replace user data on match because data in mongo is actual. Basically we can define user duplicate by matching filter like a.Username == b.Username && a.Email == b.Email
or something similar, I don't want it to be relevant to this question, let's just say there's a way we can tell if users A and B are the same.
So it seems like my only option here is using upsert Update with SetOnInsert. In C# driver there's a method Builders<User>.Update.SetOnInsert<TField>(Expression<User,TField>, TField)
but I will have to call it multiple times to enumerate all the properties. If these properties going to change in future, someone will have to update this method and I don't like it.
Is there a way to bypass this problem? Maybe by using reflecion and PropertyInfo
or by working with BsonDocument
directly? Or maybe I missing somethign and there's an easier way to do it? Thanks in advance.
Ok, so it wasn't that hard after all:
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);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.