Search code examples
c#mongodbmappingmongodb-.net-driver

MongoDB class mapping


I have following data structure

internal class FixtureNodeBase
{
  public FixtureNodeBase( string name, IEnumerable<FixtureNodeBase> children )
  {
    Name = name;
    Children = children.ToList().AsReadOnly();
  }

  public string Name { get; }

  public IReadOnlyList<FixtureNodeBase> Children { get; }
}

internal class FixtureNode : FixtureNodeBase
{
  public FixtureNode(
    string name,
    string assembly,
    string runnableName,
    IEnumerable<FixtureNodeBase> children )
    : base( name, children )
  {
    Assembly = assembly;
    RunnableName = runnableName;
  }

  public string Assembly { get; }

  public string RunnableName { get; }
}

internal class FixtureTree
{
  public FixtureTree( FixtureNodeBase root )
  {
    Root = root;
  }

  public FixtureNodeBase Root { get; }
}

internal class Build
{
  public Build( FixtureTree fixtures )
  {
    Fixtures = fixtures;
  }

  public FixtureTree Fixtures { get; }
}

for the data structure I use following mapping

BsonClassMap.RegisterClassMap<Build>(
  cm =>
  {
    cm.MapMember( x => x.Fixtures );
    cm.MapCreator( x => new Build( x.Fixtures ) );
} );

BsonClassMap.RegisterClassMap<FixtureTree>(
  cm =>
  {
    cm.MapMember( x => x.Root );
    cm.MapCreator( x => new FixtureTree( x.Root ) );
} );

BsonClassMap.RegisterClassMap<FixtureNodeBase>(
  cm =>
  {
    cm.MapMember( x => x.Name );
    cm.MapMember( x => x.Children );
    cm.MapCreator( x => new FixtureNodeBase( x.Name, x.Children ) );
} );

BsonClassMap.RegisterClassMap<FixtureNode>(
  cm =>
  {
    cm.MapMember( x => x.Name );
    cm.MapMember( x => x.Assembly );
    cm.MapMember( x => x.RunnableName );
    cm.MapMember( x => x.Children );
    cm.MapCreator( x => new FixtureNode( x.Name, x.Assembly, x.RunnableName, x.Children ) );
} );

and it throws the exception for FixtureNode mapping:

"System.ArgumentOutOfRangeException : The memberInfo argument must be for class FixtureNode, but was for class FixtureNodeBase."

LINQPad file with example can be downloaded from here example.linq

If you have any ideas, how to fix the issue, please share your idea.


Solution

  • Seems, I found my fault:

    BsonClassMap.RegisterClassMap<FixtureNode>(
      cm =>
      {
        cm.MapMember( x => x.Name );
        cm.MapMember( x => x.Assembly );
        cm.MapMember( x => x.RunnableName );
        cm.MapMember( x => x.Children );
        cm.MapCreator( x => new FixtureNode( x.Name, x.Assembly, x.RunnableName, x.Children ) );
    } );
    

    must be updated to

    BsonClassMap.RegisterClassMap<FixtureNode>(
      cm =>
      {
        cm.MapMember( x => x.Assembly );
        cm.MapMember( x => x.RunnableName );
        cm.MapCreator( x => new FixtureNode( x.Name, x.Assembly, x.RunnableName, x.Children ) );
    } );
    

    i.e. mapping for Name and Children members from base class should be removed form inherited class mapping.