BsonClassMap, to setup reference between two poco objects via a property and store the relationship as a manual reference or dbref

116 views
Skip to first unread message

Geoff

unread,
Feb 18, 2013, 8:50:36 PM2/18/13
to mongodb...@googlegroups.com
Using persistent agnostic domain objects, how do I map a reference property between two objects using BsonClassMap?

In the NH/FluentNh world (I know, relational), you would use something like:
Reference(c=>c.ReferenceProperty, "reference_id");

How do you achieve the similar sort of thing for MongoDB using BsonClassMap?  I know, no foreign keys, but the relationship can be manually encoded (as in `{entity}_id`) or as a DbRef.  The former I understand being preferred.

For example, if I have the following classes:
public class A 
{
  public Guid Id { get; protected set; }
}

public class B
{
  public Guid Id { get; protected set; }
  public A ReferenceProperty{ get; set; }
}

Where A is not an aggregate of B, and so I don't want to embed the A document within the document of B. Instead I want a reference field in the B document to the _id of the A document.

So, how would I map `ReferenceProperty` using the BsonClassMap to achieve the following document structure:

// collectionAs
{ _id: "guid-for-A" }

// collectionBs
{ _id: "guid-for-B", ReferenceProperty_id: "guid-for-A" }

I know the BsonClassMap for A and B would look something like this (with a gap in my knowledge for how to map the `ReferenceProperty`):
BsonClassMap.RegisterClassMap<A>(cm =>
{
    cm.MapIdProperty(c => c.Id)
        .SetIdGenerator(new GuidGenerator())
        .SetRepresentation(BsonType.String);
});

BsonClassMap.RegisterClassMap<B>(cm =>
{
    cm.MapIdProperty(c => c.Id)
        .SetIdGenerator(new GuidGenerator())
        .SetRepresentation(BsonType.String);

    cm.MapProperty(c => c.ReferenceProperty); // this embeds the document, how do I map a *_id field or a dbref?
});

Is this even possible, or do I need to change the model to keep it persistent agnostic  (not include MongoDbRef as the `ReferenceProperty` type, etc) to achieve this aggregate structure in the database?  A model change could be:
public class A 
{
  public Guid Id { get; protected set; }
}

public class B
{
  public Guid Id { get; protected set; }
  public Guid ReferencePropertyId{ get; set; }
}


craiggwilson

unread,
Feb 18, 2013, 9:45:19 PM2/18/13
to mongodb...@googlegroups.com
You'll need to change your ReferenceProperty to ReferencePropertyId.  We do not support lazy-loading (or eager-loading) of referenced documents.

Since A is not the aggregate for B, then this actually makes more sense when discussing in these terms.  Generally, it is unnecessary for a referenced aggregate (B) to be loaded in order to process the referencing aggregate (A).  It might be that you do indeed need some information from B.  In this case, think about denormalizing a little and creating a true entity (BSummary) whose aggregate is A.  This would make sense if some of the summary information is immutable or changes infrequently.

Geoff

unread,
Feb 18, 2013, 9:54:53 PM2/18/13
to mongodb...@googlegroups.com
Thank you for the response.  I couldn't find any information anywhere, but this is what I suspected.
Reply all
Reply to author
Forward
0 new messages