Ben Foster
Ben Foster

Reputation: 34830

MongoDB C# Driver does not automap pascal-cased properties

I'm using the official MongoDB C# driver to query an existing collection of documents that use camel-cased property names e.g. post.title.

The docs seem to suggest that nothing is required to map the documents to C# POCOs with pascal-cased property names e.g:

public class Post
{
    public ObjectId Id { get; set; }
    public string Title { get; set; }
    public string[] Tags { get; set; }
}

However, when attempting to query the collection I get the exception:

Element 'title' does not match any field or property of class MongoDBDemo.Post.

If change Post.Title to Post.title the query executed successfully.

Is there a way to tell the driver to deserialize to pascal-cased properties and serialize to camel-cased properties by default?

Upvotes: 6

Views: 4057

Answers (3)

Sнаđошƒаӽ
Sнаđошƒаӽ

Reputation: 17612

I know this is pretty old, but I found that the following can be used to map the camelCased fields in documents to PascalCased properties in C# POCOs:

var conventionPack = new ConventionPack
{
    new CamelCaseElementNameConvention()
};

ConventionRegistry.Register(
    name: "CustomConventionPack", 
    conventions: conventionPack,
    filter: t => true);

For filter I am using t => true so that this camelCase convention applies to all my entities/collections.

Advantage of this approach over using BsonElement attribute is that this approach can be used in cases when entities/POCOs do not reside in the same project as the one having mongodb driver reference in it (e.g. in repository pattern, or in the clean architecture).

Read more from the official documentation here.

Upvotes: 8

WiredPrairie
WiredPrairie

Reputation: 59783

The docs actually say the opposite:

Normally the name of the field in the database is exactly the same as the name of the field or property in your domain class, but Id is an exception and is mapped to _id in the database.

You could investigate creating your own Convention to override the names and make a Pascal based naming scheme. You could have it be automatically applied to every class you use with MongoDb for example.

Or, you could manually specify new names either through attributes:

public class Post {
    [BsonElement("title")]
    public string Title { get; set; }
}

Or, the class map:

BsonClassMap.RegisterClassMap<Post>(cm => {
    cm.AutoMap();
    cm.GetMemberMap(c => c.Title).SetElementName("title");
});

Upvotes: 4

yaoxing
yaoxing

Reputation: 4203

Add an attribute to the properties would do the trick:

public class Post
{

    [BsonElement("_id")]
    public ObjectId Id { get; set; }
    ...
}

Also, if you have anything in the database that doesn't exist in your class, add the attribute

[BsonIgnoreExtraElements(true)]

to avoid getting the previous error message.

There are some other attributes in the namespace MongoDB.Bson.Serialization.Attributes. Find the document here.

Upvotes: -1

Related Questions