Skip to content

DOCSP-42606: class maps feedback #592

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 116 additions & 3 deletions source/fundamentals/serialization/class-mapping.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@ Overview
--------

In this guide, you can learn how to customize the way the {+driver-long+}
maps BSON documents to and from {+language+} classes. You should read this page
maps BSON documents to and from {+language+} classes. You can 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.

You can also use POCO attributes to set serialization behavior. To learn
more, see the :ref:`csharp-poco` guide.

Automatic Class Mapping
-----------------------

Expand Down Expand Up @@ -69,7 +72,7 @@ class:
classMap.MapMember(p => p.Hobbies);
});

.. important::
.. important:: When to Register a Class Map

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.
Expand All @@ -95,9 +98,36 @@ 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
level by applying attributes to the class or by calling methods while registering
a class map.

.. _csharp-class-map-omit-fields:

Omit Fields
~~~~~~~~~~~

By default, the driver serializes all fields in your POCOS, whether you
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

POCOs?

define them or not. You can prevent specified fields from being
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By "define" you probably mean map/automap?. As a field in POCO is it's definition, therefore always defined.
I'd just omit that part.

serialized by using the ``UnmapMember()`` method when registering a
class map.

The following example shows how to create a class map to prevent the
``Age`` property from being serialized:

.. code-block:: csharp
:emphasize-lines: 4

BsonClassMap.RegisterClassMap<Person>(classMap =>
{
classMap.AutoMap();
classMap.UnmapMember(p => p.Age);
});

.. tip::

To learn about how to set this behavior by using a field attribute,
see the :ref:`csharp-poco-omit-fields` section of the POCOs guide.

Ignore Extra Elements
~~~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -134,6 +164,89 @@ You can also ignore any extra elements when registering a class map:
classMap.SetIgnoreExtraElements(true);
});

Identify Id Field
~~~~~~~~~~~~~~~~~

By default, the driver maps any public property named ``Id``, ``id``, or
``_id`` to the BSON ``_id`` field. To explicitly select the
property to map to the ``_id`` field, use the ``MapIdMember()`` class
map method.

The following code sample maps the ``Identifier`` property to the
``_id`` field:

.. code-block:: csharp
:emphasize-lines: 4

BsonClassMap.RegisterClassMap<Person>(classMap =>
{
classMap.AutoMap();
classMap.MapIdMember(p => p.Identifier);
});

String IDs
``````````

If you are using strings to represent your
documement IDs, you can use the ``IdMemberMap.SetSerializer()`` class
map method to serialize these values to ``ObjectId`` instances in
MongoDB. This way, you can customize how your ID values are represented
in your application while adhering to MongoDB best practices for ID
management in the database.

The following example directs the driver to serialize string ID values
as ``ObjectId`` values:

.. code-block:: csharp
:emphasize-lines: 4

BsonClassMap.RegisterClassMap<Person>(classMap =>
{
classMap.AutoMap();
classMap.IdMemberMap.SetSerializer(new StringSerializer(BsonType.ObjectId));
});

If you want the driver to generate valid 24-digit hex strings to
use as your ID values, you can chain the ``SetIdGenerator()`` method to
the ``MapIdMember()`` method and pass an instance of
``StringObjectIdGenerator``:

.. code-block:: csharp
:emphasize-lines: 4

BsonClassMap.RegisterClassMap<Person>(classMap =>
{
classMap.AutoMap();
classMap.MapIdMember(p => p.Identifier).SetIdGenerator(StringObjectIdGenerator.Instance);
});

To learn more about ID generators, see the
:ref:`csharp-poco-specify-id-gen` section of the POCOs guide.

GUID IDs
````````

If your application uses GUIDs as unique identifiers in your documents,
you can register a class map to specify how ``Guid`` values are
serialized. By default, the driver uses the
``GuidGenerator`` type to generate a unique value for the ID property.
You must specify the GUID representation by initializing a
``GuidSerializer``.

The following code specifies the ``Standard`` GUID representation when
registering the class map:

.. code-block:: csharp
:emphasize-lines: 4

BsonClassMap.RegisterClassMap<Person>(classMap =>
{
classMap.AutoMap();
classMap.IdMemberMap.SetSerializer(new GuidSerializer(GuidRepresentation.Standard));
});

To learn more about serializing GUIDs, see the :ref:`csharp-guids` guide.

Mapping with Constructors
-------------------------

Expand Down
72 changes: 67 additions & 5 deletions source/fundamentals/serialization/poco.txt
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ The following code sample maps the ``Identifier`` property to the
The ``_id`` field mapping logic described in this section only applies to the
root document and does not apply to nested documents.

.. _csharp-poco-specify-id-gen:

Specify an ID Generator
```````````````````````

Expand Down Expand Up @@ -312,7 +314,9 @@ The following table describes the ID generators available in the
public class House
{
public Guid Id { get; set; }
}
}

To learn more, see the :ref:`csharp-guids` guide.

* - ``ObjectId``
- The driver automatically uses the ``ObjectIdGenerator`` type for ID properties with
Expand Down Expand Up @@ -427,13 +431,46 @@ the default value (``null``), the driver throws an exception:
public Guid Id { get; set; }
}

.. _csharp-poco-omit-fields:

Omit Fields
~~~~~~~~~~~

By default, the driver serializes all fields in your POCOS, whether you
define them or not. To prevent the driver from serializing a specified
field, use the ``[BsonIgnore]`` attribute. The following code shows how
you can prevent the driver from serializing the ``YearBuilt`` property:

.. code-block:: csharp
:copyable: true
:emphasize-lines: 5

public class House
{
public Guid Id { get; set; }

[BsonIgnore]
public int YearBuilt { get; set; }
public string Style { get; set; }
}

Even if you define the ``YearBuilt`` property, the field is
not saved in MongoDB.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could add a reciprocal note that links to instructions for omitting during mapping.

.. note::

You can define a class map to prevent specific fields from being
serialized. To learn more and view an example, see the
:ref:`csharp-class-map-omit-fields` section of the Class Mapping
guide.

Omit Empty Fields
~~~~~~~~~~~~~~~~~

By default, the driver serializes undefined properties to fields with ``null``
values. To ignore undefined properties during serialization, use the ``[BsonIgnore]``
values. To ignore undefined properties during serialization, use the ``[BsonIgnoreIfNull]``
attribute. The following code shows how you can prevent the driver from
serializing the ``YearBuilt`` property if it is undefined:
serializing the ``Style`` property if it is undefined:

.. code-block:: csharp
:copyable: true
Expand All @@ -443,11 +480,36 @@ serializing the ``YearBuilt`` property if it is undefined:
{
public Guid Id { get; set; }

[BsonIgnore]
public int YearBuilt { get; set; }
[BsonIgnoreIfNull]
public string Style { get; set; }
public int YearBuilt { get; set; }
}

You can also instruct the driver to ignore a property that contains a
``null`` value when you register the class map, as shown in the
following example:

.. code-block:: csharp
:copyable: true
:emphasize-lines: 4

BsonClassMap.RegisterClassMap<House>(classMap =>
{
classMap.AutoMap();
classMap.MapMember(h => h.Style).SetIgnoreIfNull(true);
});

.. note:: Numerical Properties

You cannot use the ``[BsonIgnoreIfNull]`` attribute or
``SetIgnoreIfNull()`` method to prevent undefined numerical
properties from being serialized unless you mark the properties as
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"undefined numerical property" wording might be confusing for .NET users, as numeric (value) values are always defined. 'Uninitialized' or 'default' sound better.

nullable. Instead, use the ``[BsonIgnoreIfDefault]`` attribute or
``SetIgnoreIfDefault()`` class map method, which are described in the
:ref:`csharp-poco-default-values` section of this guide.

.. _csharp-poco-default-values:

Customize Default Values
~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
Loading