mongo-csharp-driver

99 views
Skip to first unread message

blu

unread,
Oct 27, 2010, 10:36:34 PM10/27/10
to mongodb-user

First, thanks for creating a C# driver in house, I have been hoping
for one. Its reassuring to see the amount of documentation already
available, and I am really looking forward to using the driver.

I have been having some fun poking the ObjectId type. Here's kind of
where I am and I appreciate any thoughts.

1) The driver only looks for a field named, "_id". In order to use
this in my app I had to make the property public. Public properties
prefixed with an "_" are basically a crime against humanity and I am
trying to figure out an alternative to this. I haven't yet.

2) The MongoDB ObjectId and .NET Guid types are straight up not
compatible with each other.
* I have thought about trimming the .net Guid and rolling with that.
* I have also thought about completely ignoring that value in my
application and only using it for internal collection mechanics like
DBRef. I am already mostly there due to URL slug constraints in a web
app.

This is the most important:
3) I violated a core DDD idiom and referenced the BsonLibrary directly
in my model so I could add a property of type ObjectId. When I did
that, the Add method jammed an ObjectId of 000000000000000000000000
into the collection.

4) As an extension on the previous item, I have also noticed the
CSharpDriver functionality does not ignore null values. The
BsonLibrary does according to the documentation, which is really great
news. The C# driver not caring is probably a by-product of the
serialization process.

Where I am now) I think I am just going to use the BsonLibrary
directly and store the Id as a string and manually map it into a
document as "_id". I'd appreciate any alternatives.

All in all I like what I see with the driver, its trim, easy to use,
nicely documented for the most part, and shows a lot of promise.

Robert Stam

unread,
Oct 28, 2010, 12:59:38 AM10/28/10
to mongodb-user
Thanks for your comments.

Serialization support will improve a lot in version 0.7, which should
be out by the end of this week. We also will be adding a section to
the online tutorial on serialization.

Regarding identifying which property of your class should be treated
as the id, version 0.7 will let you do any of the following:

1. Use the [BsonId] attribute to mark a field/property as the Id for
the object
2. Use the MapIdField or MapIdProperty methods to map a field/property
as the Id if you prefer to configure serialization in code instead of
using attributes
3. Let AutoMap find the Id, possibly registering your own
implementation of IIdMemberConvention if the default one doesn't find
your Id correctly

You won't have to name your Id property "_id"! :-)

To set your mind at ease about using attributes to decorate your
properties, it's not required. If you prefer to have persistence
ignorance in your POCOs that's fine. You'll just have to configure
your serialization another way, either manually configuring your class
maps in code, or registering custom conventions to guide AutoMap to do
the right thing. If you're lucky the standard AutoMap behavior will
work for you out of the box.

Glad you're having a good experience, and it's great to get feedback
like this. It definitely helps us make the driver better.
Message has been deleted

blu

unread,
Oct 28, 2010, 9:19:53 PM10/28/10
to mongodb-user
#2 sounds pretty good. Its nice to see you guys are iterating so
rapidly, seems like pretty good code velocity. That's reassuring,
thanks again.

blu

unread,
Dec 10, 2010, 10:34:50 PM12/10/10
to mongodb-user
Since this last post I went down the path of using raw BsonDocuments
for everything. It has given me a lot of flexibility and I got a lot
of hands on experience with the lower parts of the driver. However at
this point I am going back to look at the serialization approach to
development faster. Below is a scenario I would like to explore the
feasibility of:

1) I have a model class with property Id of type string
-- I do not want to reference the driver in this assembly to make it
an ObjectId as it is an implementation detail and does not belong in
my domain model.
2) The driver sees the property now (see above where it didn't) but it
coughs up an InvalidOperationException("Id cannot be null")

What I would expect is the driver sees the property is null, creates
the Mongo ObjectId, uses that for the _id key in the BsonDocument, and
writes the generated value back into the property as a string.

Basically, does it have an id? No, create one, else use it.

I realize the id is not restricted to ObjectId or string, and the
driver would need to know, "hey Id properties on classes should be
translated to/from ObjectIds interally but reported back as strings".

Does that make sense?

Robert Stam

unread,
Dec 10, 2010, 11:15:29 PM12/10/10
to mongodb-user
I don't see the C# driver doing magic mappings between string and
ObjectId. If your Id field is a string in your Entity it will be a
string in the database also.

If you really don't want the ObjectId datatype in your domain model I
see two options:

1. Use Guid as your Id type
2. Write a custom IdGenerator that will generate a new ObjectId and
convert it to a string

In case 2 the Id in the database will be of type string (not
ObjectId).

Here's some sample code that shows how you can use your own custom
IdGenerator to generate Ids any way you see fit:

http://www.pastie.org/1367147

blu

unread,
Dec 11, 2010, 12:24:39 AM12/11/10
to mongodb-user
Magical? OK then.

On Dec 10, 11:15 pm, Robert Stam <rstam10...@gmail.com> wrote:
> I don't see the C# driver doing magic mappings between string and
> ObjectId. If your Id field is a string in your Entity it will be a
> string in the database also.
>
> If you really don't want the ObjectId datatype in your domain model I
> see two options:
>
> 1. Use Guid as your Id type
> 2. Write a custom IdGenerator that will generate a new ObjectId and
> convert it to a string
>
> In case 2 the Id in the database will be of type string (not
> ObjectId).
>
> Here's some sample code that shows how you can use your own custom
> IdGenerator to generate Ids any way you see fit:
>
> http://www.pastie.org/1367147
>
> On Dec 10, 10:34 pm,blu<robert.schoo...@gmail.com> wrote:
>
>
>
>
>
>
>
> > Since this last post I went down the path of using raw BsonDocuments
> > for everything.  It has given me a lot of flexibility and I got a lot
> > of hands on experience with the lower parts of the driver.  However at
> > this point I am going back to look at the serialization approach to
> > development faster.  Below is a scenario I would like to explore the
> > feasibility of:
>
> > 1) I have a model class with property Id of type string
> > -- I do not want to reference the driver in this assembly to make it
> > an ObjectId as it is an implementation detail and does not belong in
> > my domain model.
> > 2) The driver sees the property now (see above where it didn't) but it
> > coughs up an InvalidOperationException("Id cannot be null")
>
> > What I would expect is the driver sees the property is null, creates
> > the Mongo ObjectId, uses that for the _id key in the BsonDocument, and
> > writes the generated value back into the property as a string.
>
> > Basically, does it have an id? No, create one, else use it.
>
> > I realize the id is not restricted to ObjectId or string, and the
> > driver would need to know, "hey Id properties on classes should be
> > translated to/from ObjectIds interally but reported back as strings".
>
> > Does that make sense?
>

Robert Stam

unread,
Dec 13, 2010, 3:09:50 PM12/13/10
to mongodb-user
By magical I mean how would the driver know what you want to happen?
Mapping a string to an ObjectId is just one possible interpretation of
what should happen.

By the way, in my previous reply I mentioned you could write a custom
IdGenerator to create new Id values that are really ObjectIds
represented as strings. Here's a small variation on that example that
adds a custom serializer so that you can use string for your Ids in
your classes yet store them as ObjectIds in the database.

http://www.pastie.org/1373993

Combining the custom IdGenerator with the custom serializer you can
get the exact behavior you wanted without any changes in the driver.

Of course, you might be better off just using Guids!

blu

unread,
Dec 22, 2010, 6:48:31 PM12/22/10
to mongodb-user
Couldn't this have been done with a representation:

cm.GetMemberMap(c => c.Id).SetRepresentation(BsonType.ObjectId);

Going into the database, cast/convert it to an ObjectId.
Coming out, cast/convert it to a string.

On Dec 13, 3:09 pm, Robert Stam <rstam10...@gmail.com> wrote:
> By magical I mean how would the driver know what you want to happen?
> Mapping a string to an ObjectId is just one possible interpretation of
> what should happen.
>
> By the way, in my previous reply I mentioned you could write a custom
> IdGenerator to create new Id values that are really ObjectIds
> represented as strings. Here's a small variation on that example that
> adds a custom serializer so that you can use string for your Ids in
> your classes yet store them as ObjectIds in the database.
>
> http://www.pastie.org/1373993
>
> Combining the custom IdGenerator with the custom serializer you can
> get the exact behavior you wanted without any changes in the driver.
>
> Of course, you might be better off just using Guids!
>
Reply all
Reply to author
Forward
0 new messages