How do you access MongoDB collections
The MongoDatabase object has a method on it called GetCollection<T> allowing you a strongly types object reference.
You are not limited to storing one type of object in a collection, but I do to keep from making mistakes, not having _id collisions, and to keep sane.
public static MongoCollection<MongoProduct> ProductCollection
= Mongo.MainDatabase.GetCollection<MongoProduct>("product");
How to set up your classes for serialization
By default, all of your properties will be serialized, as long as they are not read only (only a get)
There are many ways to set up your objects for serialization. This gives you total control over how your objects are serialized and deserialized
You can use POCO objects with no markup using the BsonClassMap
How to set up your classes for serialization
Custom Attributes
[BsonIgnoreIfNull]
[BsonElement("esrb")]
public string ESRBAgeRating {
get;
set;
}
[BsonElement("format")]
public string Format {
get;
set;
}
How to set up your classes for serialization
BsonClassMap
This will be a very familiar pattern for those that are used to AutoMapper
BsonClassMap.RegisterClassMap<MongoProduct>(cm => {
cm.AutoMap();
cm.SetIgnoreExtraElements(true);
cm.UnmapProperty(c => c.BuyItNowPrice);
cm.GetMemberMap(c => c.Format).SetIgnoreIfNull(true);
cm.GetMemberMap(c => c.Genre).SetIgnoreIfNull(true);
});
How to set up your classes for serialization
Decimal types are not supported!
How do I save them so they are not saved as strings?
How to set up your classes for serialization
Your best bet is to convert the value to an integer or long data type.
Pick a common scale for all decimals in a type (or globally) so the user will not have to guess how to convert your value back
How to set up your classes for serialization
Using another property in your class to serialize the object.
Not as clean but no mapper is needed.
This is problematic for query operations in c#.
[BsonElement("listPrice")]
public int ListPriceInteger {
get {
return (int)(ListPrice * 10000); //4 dec places
}
set {
ListPrice = value / 10000;
}
}
//MSRP
[BsonIgnore]
public decimal ListPrice {
get;
set;
}
How to set up your classes for serialization
Create a serializer and use that in your BsonClassMap to write the value
BsonClassMap.RegisterClassMap<Dimension>(cm => {
cm.AutoMap();
cm.GetMemberMap(c => c.Height).SetSerializer(new DecimalSerializer())
.SetElementName("height");
cm.GetMemberMap(c => c.Length).SetSerializer(new DecimalSerializer())
.SetElementName("length");
cm.GetMemberMap(c => c.Weight).SetSerializer(new DecimalSerializer())
.SetElementName("weight");
cm.GetMemberMap(c => c.Width).SetSerializer(new DecimalSerializer())
.SetElementName("width");
});
How to set up your classes for serialization
This is the original Dimension class. It is a POCO. All operations are performed in the BsonClassMap
public class Dimension {
public decimal Length {
get; set;
}
public decimal Height {
get; set;
}
public decimal Width {
get; set;
}
public decimal Weight {
get; set;
}
}
What does this look like in MongoDB?
"dimensions" : {
"length" : NumberLong(100400),
"height" : NumberLong(5000),
"width" : NumberLong(90100),
"weight" : NumberLong(14100)
}
More information
-
http://docs.mongodb.org/ecosystem/tutorial/serialize-documents-with-the-csharp-driver/
-
http://docs.mongodb.org/ecosystem/tutorial/use-csharp-driver/
Saving data
If you know that without a doubt that the object does not exist with the same id, you can use insert.
var product = new MongoProduct() { };
Collections.ProductCollection.Insert<MongoProduct>(product);
Saving data
If you are not sure if the id exists or you are performing an update, use the save method. This method will determine if an insert or update must happen.
If you want it to fail if the object already exists and you want it to be a new record, call insert. Save will override whatever is in the database
var product = new MongoProduct() { };
Collections.ProductCollection.Save<MongoProduct>(product);
Bulk Inserts
If you have many objects to insert at once and they are all inserts, you can use the InsertBatch method.
It takes in an IEnumerable<T>.
It is very fast. For the sample data, 25,000 records were inserted in 1600 ms
Collections.ProductCollection.InsertBatch<Product>(list);