[CSHARP-398] Can't Map Base Class Field As Id Created: 17/Feb/12  Updated: 02/Apr/15  Resolved: 17/Feb/12

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: 1.3.1
Fix Version/s: 1.4

Type: Bug Priority: Major - P3
Reporter: Tim Scott Assignee: Robert Stam
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to CSHARP-400 Improve error message in SetIdMember ... Closed

 Description   

This code from the docs:

BsonClassMap.RegisterClassMap<MyClass>(cm => {
    cm.AutoMap();
    cm.SetIdMember(cm.GetMemberMap(c => c.SomeProperty));
});

...fails if SomeProperty is on a base of MyClass.

Based on another issues I read (CSHARP-396) I thought this might work:

BsonClassMap.RegisterClassMap<BaseOfMyClass>(cm => {
    cm.SetIdMember(x.GetMemberMap(c => c.SomeProperty));
});

But that fails too. Both cases fail with cryptic message "Invalid memberMap."

The only workaround for mapping via code seems to be remove inheritance.



 Comments   
Comment by Robert Stam [ 17/Feb/12 ]

Actually, I tried to reproduce your NullReferenceException and I don't get an exception. It seems to work fine.

Full test program at: http://www.pastie.org/3404493

Comment by Robert Stam [ 17/Feb/12 ]

That is a different issue. Your Id property is defined in an interface, not in your Entity class.

Obviously that is not currently supported, though it should not have resulted in a NullReferenceException.

Comment by Tim Scott [ 17/Feb/12 ]

When I try the code in your comment I get an exception. My exact code:

BsonClassMap.RegisterClassMap<Entity>(x =>
{
    x.AutoMap();
    x.SetIdMember(x.GetMemberMap(c => c.Id));
});

public abstract class Entity : IEntity
{
    public Guid Id { get; set; }
}

The exception is a null ref on SetMemberId:

at UnitedRoad.LoadPlanner.Persistence.Impl.Mongo.<Configure>b__1(BsonClassMap`1 x) in C:\LunaverseRepositories\UnitedRoad\OvissLoadPlanner\src\UnitedRoad.LoadPlanner\Persistence\Impl\Mongo.cs:line 34
at MongoDB.Bson.Serialization.BsonClassMap`1..ctor(Action`1 classMapInitializer) in C:\work\10gen\mongodb\mongo-csharp-driver\Bson\Serialization\BsonClassMap.cs:line 1122
at MongoDB.Bson.Serialization.BsonClassMap.RegisterClassMap[TClass](Action`1 classMapInitializer) in C:\work\10gen\mongodb\mongo-csharp-driver\Bson\Serialization\BsonClassMap.cs:line 374

Comment by Robert Stam [ 17/Feb/12 ]

I'm closing this JIRA but opening a new one to improve the error message.

Comment by Robert Stam [ 17/Feb/12 ]

The key to understanding how class maps are configured, specially in an inheritance hierarchy, is that each class map only specifies how to map the properties defined in that class. Any properties defined in a base class are mapped by the class map for that class. So the correct way to register the two class maps for BaseOfMyClass and MyClass is:

 
BsonClassMap.RegisterClassMap<BaseOfMyClass>(cm =>
{
    cm.AutoMap();
    cm.SetIdMember(cm.GetMemberMap(c => c.Id));
});
BsonClassMap.RegisterClassMap<MyClass>();

Also, in many cases you don't even have to do this since classes are automapped on demand as needed. You only need to do this if you are going to create a non-standard class map>

Generated at Wed Feb 07 21:36:42 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.