2017-12-04 11 views
0

C#Mongo DBドライバのバージョン2.4.4を使用して、複雑なクラスを非直列化しようとしています。これはMongoDBに正しく格納されていますが、逆シリアル化されているときはnullです。MongoDB:複雑なオブジェクトのデシリアライズでNULLが返される

これは私のデータモデルである:

public abstract class Document 
{ 
    public DocumentId Id { get; private set; } 

    public DocumentProperty TestProperty { get; private set; } 

    protected Document() { } 

    public void SetId(string value) 
    { 
     if (string.IsNullOrEmpty(value)) throw new ArgumentNullException("value"); 
     Id = new DocumentId(value); 
    } 

    public void AddProperty(DocumentProperty property) 
    { 
     if (property == null) throw new ArgumentNullException("property"); 
     TestProperty = property; 
    } 
} 

public class DocumentId 
{ 
    public string Value { get; } 

    public DocumentId(string value) 
    { 
     Value = value; 
    } 
} 

public abstract class DocumentProperty 
{ 
    public string Value { get; } 

    protected DocumentProperty() 
    { 
    } 

    protected DocumentProperty(string value) 
    { 
     Value = value; 
    } 
} 

public class TitleDocumentProperty : DocumentProperty 
{ 
    public TitleDocumentProperty() { } 

    public TitleDocumentProperty(string value) : base(value) 
    { 
    } 
} 

これは私のマッピングコードです:

public class MongoClassMapper 
{ 
    public static void InitializeMap() 
    { 
     BsonClassMap.RegisterClassMap<DocumentProperty>(map => 
     { 
      map.MapProperty(property => property.Value).SetDefaultValue("123"); 
      map.SetIsRootClass(true); 
     }); 

     BsonClassMap.RegisterClassMap<TitleDocumentProperty>(map => 
     { 
     }); 

     BsonClassMap.RegisterClassMap<Document>(map => 
     { 
      map.MapProperty(document => document.Id); 
      map.MapProperty(document => document.TestProperty); 
      map.SetIsRootClass(true); 
     }); 

    } 
} 

これはモンゴからのデータを追加して取得するための私の方法です:

public async Task<string> Add(Document document) 
    { 
     await _documents.InsertOneAsync(document); 
     return document.Id.Value; 
    } 

    public async Task<Document> Get(DocumentId id) 
    { 
     var mongoDocuments = await _documents.Find(document => document.Id == id) 
      .ToListAsync(); 

     return mongoDocuments.SingleOrDefault(); 
    } 

これがされ私がテストに使用するコード:

private static MongoCache _cache; 

    static void Main(string[] args) 
    { 
     MongoClassMapper.InitializeMap(); 
     _cache = new MongoCache(ConfigurationManager.ConnectionStrings["connName"].ConnectionString, "dbName"); 
     string id = ItShouldCreateRecord().Result; 
     var doc = ItShouldGetRecord(id).Result; 
    } 

    private static Task<string> ItShouldCreateRecord() 
    { 
     //Arrange 
     Document document = new FakeDocument(); 
     document.SetId(Guid.NewGuid().ToString()); 
     document.AddProperty(new TitleDocumentProperty("this is a title")); 

     //Act 
     string id = _cache.Add(document).Result; 

     //Assert 
     //Assert.NotEmpty(id); 
     return Task.FromResult(id); 
    } 

    private static Task<Document> ItShouldGetRecord(string id) 
    { 
     //Arrange 

     //Act 
     return _cache.Get(new DocumentId(id)); 

     //Assert 
     //Assert.NotNull(doc); 
    } 
} 

[BsonIgnoreExtraElements] 
public class FakeDocument : Document 
{ 
} 

DBから_cache.Get()を使用してドキュメントを取得すると、プロパティのTestPropertyが実際の値を持つことが予想されます。現在はNULLです。

答えて

1

問題はMongoDBは、このプロパティをデシリアライズないようになりますあなたのValue財産上のセッターが存在しないことである:

public abstract class DocumentProperty 
{ 
    public string Value { get; /* no setter*/ } 
} 

あなたは単に、任意のアクセシビリティの設定を使用して(でもプライベートセッターを追加することによってこの問題を解決することができます)作品:私はそれが固定取得するJIRA issuepull requestをキャプチャしている

public abstract class DocumentProperty 
{ 
    public string Value { get; /* private if you want */ set; } 
} 

+0

十分にありがとうございます! さまざまなことを試して、勤務時間全体を費やしました。(カスタムシリアライザ、カスタムタイプフォーマッタ)、ソリューションはとてもシンプルでした。ありがとうございました! – Hos

関連する問題