2011-10-08 3 views
16

클래스가 User이고 웹 서비스에서 이들과 작업해야합니다.MongoDB C# : ID 직렬화 최상의 패턴

그런 문제 내가 BsonObjectId의 유형이 그 Id를 직렬화하려고하면, 나는 빈 속성이 그 빈 속성이 를 참조 등등 ...

내가이 해결 방법을 쓰기 가지고있다 순서대로, 그것은 좋은 해결책인가? 이런 식으로

public partial class i_User 
{ 
    [BsonId(IdGenerator = typeof(BsonObjectIdGenerator))] 
    [NonSerialized] 
    public BsonObjectId _id; 

    public String Id 
    { 
     get 
     { 
      return this._id.ToString(); 
     } 
    } 
} 

, 나는 BsonObjectId_Id을 유지할 수 있지만 재산 Id에서 웹을 통해 캐릭터 라인 표현을 보낼 수 있습니다.

또 다른 해결책은 StringObjectIdGenerator

public partial class i_User 
{ 
    [BsonId(IdGenerator = typeof(StringObjectIdGenerator))] 
    public String id; 
} 

작업을하지만, MongoDB를이 ObjectId 대신 데이터베이스에 string를 저장하는 것을 볼이다.

웹 서비스 및/또는 클라이언트 - 서버 (Flash + C#)와 같은 직렬화 환경에서 작동하려면 어떤 방법이 가장 좋습니까?

답변

90

올바르게 이해하면 Id 속성을 문자열로 액세스하려고하지만 Id은 MongoDB에 ObjectId으로 저장해야합니다. 이는 BsonRepresentationBsonId을 사용하여 수행 할 수 있습니다.

[BsonId] 
[BsonRepresentation(BsonType.ObjectId)] 
public string Id { get; set; } 

세부 사항은 here입니다.

+3

고마워요! 내가 할 수 있으면 두 번 투표 할 것입니다.) – Doobi

+1

방금 ​​내 날을 저장했습니다 – emreturan

+1

원시 ObjectId를 직렬화하지 않을 webapi 응답에 2 시간을 소비했습니다. 이것은 나를 아마 2 시간 더 절약했다 –

6

당신은 클래스 맵을 함께하고 싶어 -이 할 수있는 방법은 다음과 같습니다 규칙를 사용하여보다 일반적인 접근 방식은 또한

BsonClassMap.RegisterClassMap<i_User>(cm => 
{ 
    cm.AutoMap(); 
    cm.SetIdMember(cm.GetMemberMap(x => x.Id) 
    .SetIdGenerator(StringObjectIdGenerator.Instance)); 
}); 
+0

이것은 POCO가 가장 중요한 관심사 인 깨끗한 상태로 유지되는 아주 좋은 방법입니다. 하지만 실제로 이드를 몽고의 문자열로 저장합니다. 이상적인 방법은 데이터베이스에서 ObjectId 표현을 사용하고 POCO에서 문자열 표현을 사용하는 것입니다. 그게 가능하니? –

+0

내가 아는 것은 아니지만 C# 드라이버를 수정할 수 있다고 생각합니다. ObjectId를 사용하는 목적은 12 바이트 만 소요되고 타임 스탬프에 빌드가 있음을 의미합니다. 도메인 엔티티에서 ObjectId를 사용하지 않는 이유는 무엇입니까? – Lybecker

+1

빠른 답변을 보내 주셔서 감사합니다. 나는 보통 내 도메인 계층에 스토리지 계층 기술을 독립적으로 사용하고자합니다. 그러나 나는 모든 것이 상쇄되는 것이라고 생각한다. –

1

있습니다. 이 방법을 사용하면 한 곳에서 모든 모델에 대한 규칙을 설정할 수 있습니다.

처음. ID 생성기 규칙을 추가하십시오.

public class IdGeneratorConvention : ConventionBase, IPostProcessingConvention 
{ 
    public void PostProcess(BsonClassMap classMap) 
    { 
     var idMemberMap = classMap.IdMemberMap; 
     if (idMemberMap == null || idMemberMap.IdGenerator != null) 
     { 
      return; 
     } 

     idMemberMap.SetIdGenerator(StringObjectIdGenerator.Instance); 
    } 
} 

초. 우리 대회를 등록하십시오. 첫 번째 쿼리 전에 Register 메서드는 이라고 지정해야합니다.

var conventionPack = new ConventionPack { new IdGeneratorConvention() }; 
ConventionRegistry.Register("Pack", conventionPack, x => true);