2

I'm having problems with mapping some classes using BsonClassMap. I've 3 classes like this:

abstract class A {
  public string FirstName { get; set; }
}

abstract class B : A{
  public string LastName { get; set; }
}

class C : B {
  public int Age { get; set; }
}

I want only properties visible in the class C to be mapped to database.

BsonClassMap.RegisterClassMap<C>(map =>
{
  map.MapProperty(c => c.FirstName).SetElementName("fn");
  map.MapProperty(c => c.LastName).SetElementName("ln");
  map.MapProperty(c => c.Age).SetElementName("age");
});

This throws an exception and from what I've manage to find out it seems to be because the properties don't belong to the C class. How should i map this kind of structure ?

1
  • Could you include the exception message and stacktrace, please? Commented Mar 12, 2012 at 16:48

2 Answers 2

5

The way class maps work in an inheritance hierarchy is that you register a class map for each class in the hierarchy, and each class map defines only the properties present in that class. So you want to register all three classes like this:

BsonClassMap.RegisterClassMap<A>(map =>
{
    map.MapProperty(a => a.FirstName).SetElementName("fn");
});
BsonClassMap.RegisterClassMap<B>(map =>
{
    map.MapProperty(b => b.LastName).SetElementName("ln");
});
BsonClassMap.RegisterClassMap<C>(map =>
{
    map.MapProperty(c => c.Age).SetElementName("age");
});

You can test it quickly with some code like this:

var document = new C { FirstName = "John", LastName = "Doe", Age = 33 };
Console.WriteLine(document.ToJson());

which outputs:

{ "fn" : "John", "ln" : "Doe", "age" : 33 }

Or you can use attributes to annotate your classes, which is often much easier, but does require creating a dependency on the C# driver in your data model classes.

Sign up to request clarification or add additional context in comments.

Comments

0

You can add the BsonIgnore attribute to the properties of class A that you do not want to have stored in the database. Just add [BsonIgnore] above the property and it will be ignored.

There is also a BsonIgnoreIfNull attribute that does just what it says - ignores the element if the value is null. Very useful in cases where you dont want to null values in the database and waste disk\memory.

Also, you can use the BsonElement attribute to change the name:

abstract class B : A{
  [BsonElement("ln")]
  public string LastName { get; set; }
}
class C : B {
  [BsonElement("age")]
  public int Age { get; set; }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.