Class Mapping
On this page
Overview
In this guide, you can learn how to customize the way the MongoDB .NET/C# Driver maps BSON documents to and from C# classes. You should read this page to learn more about the default class mapping behavior, or if you need to customize the way the driver serializes or deserializes your data.
Automatic Class Mapping
When you use a class, rather than a BsonDocument
, to represent data in a
MongoDB collection, the .NET/C# Driver automatically creates a class map
that it uses to serialize or deserialize your data. It does this mapping by matching
the name of the field in the document to the name of the property in the class.
Important
The type of the property in your class should match the type of the field in the document. The .NET/C# Driver instantiates a serializer based on the type of the property in your class. If the types don't match when the driver attempts to deserialize the data, the serializer throws an exception.
Manually Creating A Class Map
You can bypass the driver's automatic class mapping functionality, and manually
define the class map by using the RegisterClassMap()
method.
The following example defines a Person
class:
public class Person { public string Name { get; set; } public int Age { get; set; } public List<string> Hobbies {get; set;} }
The following code demonstrates how to register the class map for the Person
class:
BsonClassMap.RegisterClassMap<Person>(classMap => { classMap.MapMember(p => p.Name); classMap.MapMember(p => p.Age); classMap.MapMember(p => p.Hobbies); });
Important
You must register a class map before it's needed in your code. We recommend registering class maps prior to initializing a connection with MongoDB.
You can also manually map a subset of class properties, while still
allowing the driver to automatically map the remaining properties. To do this,
register a class map and call the AutoMap()
method before manually
specifying your properties.
In the following code example, the AutoMap()
method maps all properties
of the Person
class, then manually adjusts the mapping for the Hobbies
field:
BsonClassMap.RegisterClassMap<Person>(classMap => { classMap.AutoMap(); classMap.MapMember(p => p.Hobbies).SetElementName("favorite_hobbies"); });
Customize Class Serialization
You can customize how the driver serializes and deserializes documents at the class level by using attributes with the class or by calling methods while registering a class map.
Ignore Extra Elements
When a BSON document is deserialized to a C# class, the .NET/C# Driver looks at the name of each field in the document and tries to find a matching property name in the class. By default, if a field in the document doesn't have a match in the class, the driver throws an exception.
You can choose to ignore any elements that do
not have a matching class property by using the BsonIgnoreExtraElements
attribute.
This prevents the driver from throwing an exception, and maps any other fields
that have matching class properties.
The following example shows how to add a BsonIgnoreExtraElements
attribute
to a class.
[ ]public class Person { public string Name { get; set; } public int Age { get; set; } public List<string> Hobbies {get; set;} }
You can also ignore any extra elements when registering a class map:
BsonClassMap.RegisterClassMap<Person>(classMap => { classMap.AutoMap(); classMap.SetIgnoreExtraElements(true); });
Mapping with Constructors
By default, the .NET/C# Driver can automatically map a class only if the class has
a constructor with no arguments. If you want the driver to use a constructor that accepts
one or more arguments, you can add the BsonConstructor
attribute to the constructor.
In this case, the driver examines the types to determine how to map the
constructor arguments to class properties or fields.
When the driver creates a class map for the following Person
class, it will use the
constructor marked with the BsonConstructor
attribute. The name
argument will
map to the Name
property and the age
argument will map to the Age
property.
public class Person { public string Name { get; set; } public int Age { get; set; } public List<string> Hobbies {get; set;} [ ] public Person(string name, string age) { Name = name; Age = age; } }
Tip
Multiple BsonConstructor attributes
If there is more than one constructor with the BsonConstructor
attribute, the driver uses the constructor that has the most
parameters with matching fields in the document.
You can also specify the constructor to use when registering your class map:
public class Person { public string Name { get; set; } public int Age { get; set; } public List<string> Hobbies {get; set;} public Person(string name, string age) { Name = name; Age = age; } } BsonClassMap.RegisterClassMap<Person>(classMap => { classMap.AutoMap(); classMap.MapCreator(p => new Person(p.Name, p.Age)); });
Customize Property Serialization
You can customize how the driver serializes a class property by adding attributes to the property. For more information about custom property serialization, see Custom Serialization.
Support Extra Elements
You can design your C# class to store any extra elements in your
document that don't have matching class properties. To do this your class must
have a BsonDocument
type property to hold the extra elements.
The following code uses the BsonExtraElements
attribute with the
ExtraElements
property to direct the driver to store extra elements:
public class Person { public string Name { get; set; public int Age { get; set; } public List<string> Hobbies {get; set;} [ ] public BsonDocument ExtraElements {get; set;} }
You can also support extra elements when initializing a class map as follows:
BsonClassMap.RegisterClassMap<Person>(classMap => { classMap.AutoMap(); classMap.MapExtraElementsMember(p => p.ExtraElements); });
Note
After the driver serializes a class with extra elements back to BSON, the extra elements may not be in the same order as they were in the original document.
Dynamically Serialize Properties
You can use a method to determine whether or not to serialize a property. For
the driver to automatically use the method when serializing, you must prefix the
method name with ShouldSerialize
followed by the name of the property that
the method applies to. When the driver sees a method with this naming
convention, it uses that method to determine whether or not to serialize
properties that have the provided property name.
The following example creates a method that only serializes the Age
property
if its value is not equal to 0
. The driver does not serialize any properties
whose values don't meet this requirement:
public class Person { public string Name { get; set; } public int Age { get; set; } public List<string> Hobbies {get; set;} public bool ShouldSerializeAge() { return Age != 0; } }
You can also specify the method while registering a class map:
BsonClassMap.RegisterClassMap<Employee>(classMap => { classMap.AutoMap(); classMap.MapMember(p => c.Age).SetShouldSerializeMethod( obj => ((Person) obj).Age != 0 ); });
Additional Information
For more information on using C# classes, see POCOs.