2017-09-07 4 views
1

일부 POCO 유형이 User이고 앞으로 속성이 변경 될 우려가 있습니다. 나는 데이터를 저장할 Users 콜렉션을 가진 mongodb를 가지고있다. 고유성 제약이 없으며 불행하게도 만들 수 없습니다. 내 앱은 제 3 자 아카이브 소스에서 많은 오래된 사용자를 가져오고 이러한 사용자를 mongo에 쓸 수 있기를 원하지만 복제본을 원하지 않고 mongo의 데이터가 일치하기 때문에 사용자 데이터를 바꿀 필요가 없습니다. 실제입니다. 기본적으로 우리는 a.Username == b.Username && a.Email == b.Email과 비슷한 필터를 사용하여 사용자 복제본을 정의 할 수 있습니다.이 질문과 관련되지 않기를 바랍니다. 사용자 A와 B가 동일한 지 여부를 알 수있는 방법이 있습니다.MongoDB C# 드라이버 : 존재하지 않는 경우 문서 만들기

그래서 내 유일한 옵션은 SetOnInsert로 upsert 업데이트를 사용하고있는 것 같습니다. C# 드라이버에는 메서드 Builders<User>.Update.SetOnInsert<TField>(Expression<User,TField>, TField)이 있지만 여러 번 호출하여 모든 속성을 열거해야합니다. 이러한 속성이 향후 변경 될 경우 누군가가이 메서드를 업데이트해야하며이 메서드는 마음에 들지 않습니다.

이 문제를 무시할 수있는 방법이 있습니까? 어쩌면 reflecion과 PropertyInfo을 사용하거나 BsonDocument과 직접 작업 할 수 있습니까? 또는 어쩌면 나는 somethign를 놓치고 그것을하는 쉬운 방법 있는가? 미리 감사드립니다.

답변

1

좋아, 그래서 어려운 결국하지 않았다 :

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); 
관련 문제