[CSHARP-2550] MongoDb c# driver mapping on derived class for base class members Created: 18/Mar/19  Updated: 02/Apr/20  Resolved: 02/Apr/20

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

Type: Task Priority: Major - P3
Reporter: Jakub Dropia Assignee: Wan Bachtiar
Resolution: Done Votes: 0
Labels: question
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Hi! 

I have a such class structure:

public abstract class Entity : IEntity
{
    [BsonId]
    [JsonIgnore]
    private ObjectId _id;
    
    protected Entity()
    {
        Id = Guid.NewGuid().ToString();
    }
 
    public string Id { get; private set; }
}
 
public class Device : Entity
{
 //Some fields
}
 
public class User : Entity
{
 //Some fields
}

Basically what i would like to do, is class mapping (via convention), which map Id field on base type Entity for each derived type differently in that convention:

Id -> entityId

Examples:

 

Id -> deviceId for Device Document
Id -> userId for User Document

I tried using IPostProcessingConvention, but when i request Mongo for Device object, it first doing map for Device class, and then for base type. AllMapMembers collection is empty. BaseClassMap is null.

I thought that this is due to incorrect ordering which auto-resolver map classes (first Derived Type, then base type), but when i forced this manually (by requesting first Entity, and then Device, mapping launch in correct oder that way),  AllMapMembers still are empty, and BaseClassMap is null. 

It seems that something is broken, or maybe i misunderstood those properties.

Can you explain for what reason are there, and if my mapping rules are achievable in current version of MongoDB C# driver? 



 Comments   
Comment by Wan Bachtiar [ 24/May/19 ]

Basically what i would like to do, is class mapping (via convention), which map Id field on base type Entity for each derived type differently in that convention

Hi Jakub,

Could you clarify what you would like to achieve by providing a snippet code on how you would use the class mappings ?

Are you wanting a way to dynamically change Id attribute for each of the derived class ? For example, the Id attribute is DeviceId instead of Id from the parent ?

If so, perhaps the following is what you're looking for:

public class Entity
{
    [BsonId]
    private ObjectId _id;
    protected Entity()
    {
        Id = Guid.NewGuid().ToString();
    }
    public string Id { get; private set; }
}
 
public class Device: Entity 
{
    public string DeviceId {get => Id;}
    public string Foo {get; set;}
}

Then you can use:

    var filter = Builders<Device>.Filter.Empty;
    var document = collection.Find<Device>(filter).FirstOrDefault(); 
    Console.WriteLine(document.DeviceId); 

Note that in order for auto-mapping to map a field it has to be read-write. The private set in your example may be preventing to do what you're trying to achieve.

Regards,
Wan.

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