2011-09-02 3 views
13

공식 C# 드라이버를 사용하여 몽고 db를 업서 딩하는 동안 문제가 있습니다.몽고 DB 및 ID 문제에서의 업 그레 이드

public abstract class AggregateRoot 
{ 
    /// <summary> 
    /// All mongoDb documents must have an id, we specify it here 
    /// </summary> 
    protected AggregateRoot() 
    { 
     Id = ObjectId.GenerateNewId(); 
    } 

    [BsonId] 
    public ObjectId Id { get; set; } 
} 

내 실체는 이미 ID-S를 가지고 있지만 콜렉션의 모든 문서가 하나가 있어야으로, 작동하기위한 몽고 특정 ID를 작성했다. 이제 내 시스템에 새로운 엔티티가 생겼다. 새로운 몽고 ID가 생성되고 문고가 문서의 _id를 바꿀 수 없다. 예외. 몇 가지 해결 방법이 있습니까?

조금 설명해 드리겠습니다. 이 문서로 저장된 모든 항목은 의 ID 생성을 가진 AggregateRoot에서 상속되었습니다. 모든 하위 문서는 ID가 으로 자동 생성되었으며이 문제는 발생하지 않았습니다. MongoCollection에서 List로 데이터를 검색 할 때 AggregateRoot 의 id가 문제를 해결하기 위해 도입되었으며 생성이 도입되어 id-s 이 서로 다릅니다. 이제 update를위한 새로운 엔티티가 새로운 id 생성을 가지므로 메소드를 저장하기 위해 id 생성을 이동할 수 있습니다. 그러나 은 팀의 모든 개발자가 위험한 저장소에 ID- 을 생성하는 것을 잊지 말아야 함을 의미합니다. 그냥 가능한 경우 몽고에서 매핑보다 ID 를 무시하고 명시 적으로 삽입 및 업데이트 모두에 대해 Id 값을 설정 할 수있는 것 같은데 모든

+0

개체를 어떻게 저장하고 있습니까? BsonId 속성은 MongoDB가 그 필드를 당신의 id로 사용하도록해야합니다. –

+0

데이터는 저장을 위해 외부 시스템에서 가져온 것입니다. 그것은 저장해야만하는 고유 ID를 가지고 있습니다. 그리고 이것은 Mongo와의 호환성을 위해 가짜 ID입니다. 모든 문서는 AggregateRoot에서 상속되므로 모든 객체를 수신 할 때 생성됩니다. 동일한 데이터를 수신 할 수도 있지만 생성 된 몽고 ID는 다릅니다. 따라서 예외가 나타납니다 –

답변

8

에서 AggregateRoot 클래스를 가지고 있지 좋을 것입니다. 삽입에 대해서는 문제가 없지만 새로운 모든 객체에는 _id 값이 필요하지만 업데이트의 경우 기존 문서에서 값을 변경 한 후에는 _id 값을 변경할 수 없습니다.

Id 값을 전혀 설정하지 마십시오. 삽입하기 전에 값을 지정하지 않으면 드라이버는 내장 된 IdGenerator 클래스를 사용하여 새 _id 값을 생성하므로 ObjectId 유형 인 경우 ObjectIdGenerator을 사용합니다. 그렇다면 삽입과 업데이트가 잘 작동합니다.

+0

id 속성을 제거하면 엔티티를 저장/업데이트하는 데 문제가 없습니다. 문제는 존재하지 않는 속성에 _id를 매핑 할 수 없기 때문에 코드에서 컬렉션을 검색하려고 할 때 예외가 throw된다는 것입니다. –

+2

콜렉션에 '{BsonIgnoreExtraElements}'속성을 사용할 수 있습니다. 일치하는 속성이 있습니다. –

50

비슷한 문제가 발생했습니다. 공식 C# 드라이버를 사용하여 문서를 업서 트하려고했습니다. 콘솔에서

public class MyClass 
{ 
    public ObjectId Id { get; set; } 
    public int Field1 { get; set; } 
    public string Field2 { get; set; } 
} 

내가 작성합니다 : db.collection.update({Field1: 3},{Field1: 3, Field2: "value"})하고 일하는 것이이 같은 클래스를했다. C#에서는 다음과 같이 썼습니다 :

collection.Update(Query.EQ("Field1", 3), 
       Update.Replace(new MyClass { Field1 = 3, Field2 = "value" }), 
       UpdateFlags.Upsert); 

그리고 작동하지 않았습니다! 드라이버가 업데이트 문에 빈 ID를 포함하고 있기 때문에 Field1 예외 값이 다른 두 번째 문서를 올리면 E11000 duplicate key error index 예외가 발생합니다 (이 경우 Mongo는 이미 db에있는 _id와 함께 문서를 삽입하려고합니다).

내가 혼자서 _id를 만들었 으면 (예 : 주제 시동기와 마찬가지로) Field1의 기존 값으로 개체를 업 서핑하는 것과 동일한 예외 (mongo cannot change _id of a document)가 발생했습니다.

해결책은 ID 속성을 속성 [BsonIgnoreIfDefault]으로 표시하고 초기화하지 않습니다. 이 경우 드라이버는 update 문에서 _id 필드를 생략하고 필요한 경우 MongoDb가 ID를 생성합니다.

+8

당신은 남자를 지배합니다, [BsonIgnoreIfDefault]는 엄청난 시간을 절약했습니다. 더 많은 투표를 할 수있는 것은 부끄러운 일입니다. –

+2

약 2.0 시간 동안 ReplaceOneAsync 호출이 작동하지 않는 이유를 알아 내려고 낭비했습니다. 이 대답을 찾았습니다. [BsonIgnoreIfDefault] 추가 및 문제 해결. 감사! – BrandonLWhite

+1

나는 이것을 알아 내려고 노력했다. 감사! – bbrez1

관련 문제