Jonathan Birkholz

Basic NoRM Ids

Again I want to reiterate I am by no means an expert at Mongo DBs or NoRM, but I am sure there are tons of people like me looking for some of the basics. And maybe some of the things I learn will help others.

When you start with NoRM you might quickly discover that if you don’t have an id for your object, you can’t insert or update that object.

When you try to insert an object without an identifier, you receive an MongoException that says:

This collection does not accept insertions/updates, this is due to the fact that the collection’s type does not specify an identifier property

So how can we specify an identifier property?

The basic methods include

  • Use Id property of ObjectId type
  • Use Guid property type and identify with MongoIdentifier attribute
  • Use Guid property type and map as id with MongoConfigurationMap

ObjectIds

The easy method is to use a property of type ObjectId (NoRM type) and named Id. In my learning project I am using this with Book.

1
2
3
4
5
6
public class Book
{
public ObjectId Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
}

This property is also set once you insert a new book into a collection as demonstrated here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[SetUp]
public void setup()
{
Mongo mongo = MongoTestHelper.create_new_database_connection();
mongo.Database.DropCollection(typeof (Book).Name);
_book = new Book();
mongo.GetCollection<Book>().Insert(_book);
}
[Test]
public void should_set_id_on_insert()
{
_book.Id.ShouldNotBe(ObjectId.Empty);
}

Guid + MongoIdentifier

Another method is to use a Guid and then mark that Id property with a MongoIdentifier Attribute. In my learning project I am using this with Movie.

1
2
3
4
5
6
7
8
9
10
11
12
public class Movie
{
public Movie()
{
Id = Guid.NewGuid();
}
[MongoIdentifier]
public Guid Id { get; set; }
public string Title { get; set; }
}

Notice that although I labeled the Id property with the MongoIdentifier attribute, it doesn’t automatically get set. I have to set the id to a new guid in the constructor.

Repeating the previous test shows that yes our movie can be inserted and the id set.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[SetUp]
public void setup()
{
Mongo mongo = MongoTestHelper.create_new_database_connection();
mongo.Database.DropCollection(typeof (Movie).Name);
_movie = new Movie();
mongo.GetCollection<Movie>().Insert(_movie);
}
[Test]
public void should_set_id_on_insert()
{
_movie.Id.ShouldNotBe(Guid.Empty);
}

This test really isn’t that helpful since we set the new guid in the default constructor. Let’s test that the Id can be read and set from the database.

1
2
3
4
5
6
7
8
[Test]
public void should_read_and_set_id()
{
MongoQueryProvider provider = MongoTestHelper.create_query_provider();
Movie movie = new MongoQuery<Movie>(provider).First();
movie.Id.ShouldBe(_movie.Id);
}

Using Mongo Configuration Map

If you are like me and prefer the POCO lifestyle, you can use a MongoConfigurationMap to specify the identifier.

In my learning project I am using this with Customer.

1
2
3
4
5
6
7
8
9
10
public class Customer
{
public Customer()
{
Id = Guid.NewGuid();
}
public Guid Id { get; set; }
public string Name { get; set; }
}

And then I am creating a map for customer.

1
2
3
4
5
6
7
8
9
10
11
public class CustomerMap : MongoConfigurationMap
{
public CustomerMap()
{
For<Customer>(x =>
{
x.IdIs(c => c.Id);
x.ForProperty(c => c.Name);
});
}
}

And the tests…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[SetUp]
public void setup()
{
Mongo mongo = MongoTestHelper.create_new_database_connection();
mongo.Database.DropCollection(typeof (Customer).Name);
_customer = new Customer();
mongo.GetCollection<Customer>().Insert(_customer);
}
Customer _customer;
[Test]
public void should_read_and_set_id()
{
MongoQueryProvider provider = MongoTestHelper.create_query_provider();
Customer customer = new MongoQuery<Customer>(provider).First();
customer.Id.ShouldBe(_customer.Id);
}
[Test]
public void should_set_id()
{
_customer.Id.ShouldNotBe(Guid.Empty);
}

So those are three basic methods of setting an identifier for an object to be inserted or updated in a MongoDB with NoRM. All the code is in my learning git hub repository in the Learning_NoRM solution. The source can be found here : http://github.com/RookieOne/Learning