http://www.mongodb.org/display/DOCS/CSharp+Driver+Tutorial

CSharp Driver Tutorial

C# Driver version v1.0

This tutorial is for v1.0 of the C# Driver.

Introduction

This tutorial introduces the 10gen supported C# Driver for MongoDB. The C# Driver consists of two libraries: the BSON Library and the C# Driver. The BSON Library can be used independently of the C# Driver if desired. The C# Driver requires the BSON Library.

You may also be interested in the C# Driver Serialization Tutorial. It is a separate tutorial because it covers quite a lot of material.

Downloading

The C# Driver is available in source and binary form. While the BSON Library can be used independently of the C# Driver they are both stored in the same repository.

The source may be downloaded from github.com.

We use msysgit as our Windows git client. It can be downloaded from: http://code.google.com/p/msysgit/.

To clone the repository run the following commands from a git bash shell:

$ cd <parentdirectory>
$ git config --global core.autocrlf true
$ git clone git://github.com/mongodb/mongo-csharp-driver.git
$ cd mongo-csharp-driver
$ git config core.autocrlf true
You must set the global setting for core.autocrlf to true before cloning the repository. After you clone the repository, we recommend you set the local setting for core.autocrlf to true (as shown above) so that future changes to the global setting for core.autocrlf do not affect this repository. If you then want to change your global setting for core.autocrlf to false run:

$ git config --global core.autocrlf false
The typical symptom of problems with the setting for core.autocrlf is git reporting that an entire file has been modified (because of differences in the line endings). It is rather tedious to change the setting of core.autocrlf for a repository after it has been created, so it is important to get it right from the start.

You can download a zip file of the source files (without cloning the repository) by clicking on the Downloads button at:

http://github.com/mongodb/mongo-csharp-driver

You can download binaries (in both .msi and .zip formats) from:

http://github.com/mongodb/mongo-csharp-driver/downloads

Building

We are currently building the C# Driver with Visual Studio 2008 and Visual Studio 2010. There are two solution files, one for each version of Visual Studio. The names of the solution files are CSharpDriver-2008.sln and CSharpDriver-2010.sln. The project files are shared by both solutions.

Dependencies
The unit tests depend on NUnit 2.5.9, which is included in the dependencies folder of the repository. You can build the C# Driver without installing NUnit, but you must install NUnit before running the unit tests (unless you use a different test runner).

Running unit tests
There are three projects containing unit tests:

1. BsonUnitTests
2. DriverUnitTests
3. DriverOnlineUnitTests

The first two do not connect to a MongoDB server. DriverOnlineUnitTests connects to an instance of MongoDB running on the default port on localhost.

An easy way to run the unit tests is to set one of the unit test projects as the startup project and configure the project settings as follows (using BsonUnitTests as an example):

On the Debug tab:
Set Start Action to Start External Program
Set external program to: C:\Program Files (x86)\NUnit 2.5.9\bin\net-2.0\nunit.exe
Set command line aguments to: BsonUnitTests.csproj /run
Set working directory to: the directory where BsonUnitTest.csproj is located
The exact location of the nunit.exe program might vary slightly on your machine.

To run the DriverUnitTests or DriverOnlineUnitTests perform the same steps (modified as necessary).

Installing

If you want to install the C# Driver on your machine you can use the setup program (see above for download instructions). The setup program is very simple and just:

Copies the DLLs to C:\Program Files (x86)\MongoDB\CSharpDriver 1.0
Installs the DLLs in the Global Assembly Cache (the GAC)
Configures Visual Studio to include the C# Driver DLLs in the .NET tab of the Add Reference dialog
If you downloaded the binaries zip file simply extract the files and place them wherever you want them to be.

References and namespaces

To use the C# Driver you must add references to the following DLLs:

MongoDB.Bson.dll
MongoDB.Driver.dll
You also will likely want to add the following using statements to your source files:

using MongoDB.Bson;
using MongoDB.Driver;
You might need to add some of the following using statements if you are using some of the optional parts of the C# Driver:

using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Bson.Serialization.Conventions;
using MongoDB.Bson.Serialization.IdGenerators;
using MongoDB.Bson.Serialization.Options;
using MongoDB.Bson.Serialization.Serializers;
using MongoDB.Driver.Builders;
using MongoDB.Driver.GridFS;
using MongoDB.Driver.Wrappers;
The BSON Library

The C# Driver is built on top of the BSON Library, which handles all the details of the BSON specification, including: I/O, serialization, and an in-memory object model of BSON documents.

The important classes of the BSON object model are: BsonType, BsonValue, BsonElement, BsonDocument and BsonArray.

BsonType
This enumeration is used to specify the type of a BSON value. It is defined as:

    public enum BsonType {
        Double = 0x01,
        String = 0x02,
        Document = 0x03,
        Array = 0x04,
        Binary = 0x05,
        Undefined = 0x06,
        ObjectId = 0x07,
        Boolean = 0x08,
        DateTime = 0x09,
        Null = 0x0a,
        RegularExpression = 0x0b,
        JavaScript = 0x0d,
        Symbol = 0x0e,
        JavaScriptWithScope = 0x0f,
        Int32 = 0x10,
        Timestamp = 0x11,
        Int64 = 0x12,
        MinKey = 0xff,
        MaxKey = 0x7f
    }
BsonValue and subclasses
BsonValue is an abstract class that represents a typed BSON value. There is a concrete subclass of BsonValue for each of the values defined by the BsonType enum. There are several ways to obtain an instance of BsonValue:

Use a public constructor (if available) of a subclass of BsonValue
Use a static Create method of BsonValue
Use a static Create method of a subclass of BsonValue
Use a static property of a subclass of BsonValue
Use an implicit conversion to BsonValue
The advantage of using the static Create methods is that they can return a pre-created instance for frequently used values. They can also return null (which a constructor cannot) which is useful for handling optional elements when creating BsonDocuments using functional construction. The static properties refer to pre-created instances of frequently used values. Implicit conversions allow you to use primitive .NET values wherever a BsonValue is expected, and the .NET value will automatically be converted to a BsonValue.

BsonValue has the following subclasses:

BsonArray
BsonBinaryData
BsonBoolean
BsonDateTime
BsonDocument
BsonDouble
BsonInt32
BsonInt64
BsonJavaScript
BsonJavaScriptWithScope (a subclass of BsonJavaScript)
BsonMaxKey
BsonMinKey
BsonNull
BsonObjectId
BsonRegularExpression
BsonString
BsonSymbol
BsonTimestamp
BsonUndefined
BsonType property

BsonValue has a property called BsonType that you can use to query the actual type of a BsonValue. The following example shows several ways to determine the type of a BsonValue:

    BsonValue value;
    if (value.BsonType == BsonType.Int32) {
        // we know value is an instance of BsonInt32
    }
    if (value is BsonInt32) {
        // another way to tell that value is a BsonInt32
    }
    if (value.IsInt32) {
        // the easiest way to tell that value is a BsonInt32
    }
As[Type] Properties

BsonValue has a number of properties that cast a BsonValue to one of its subclasses or a primitive .NET type:

AsBoolean (=> bool)
AsBsonArray
AsBsonBinaryData
AsBsonDocument
AsBsonJavaScript // also works if BsonType == JavaScriptWithScope
AsBsonJavaScriptWithScope
AsBsonMaxKey
AsBsonMinKey
AsBsonNull
AsBsonRegularExpression
AsBsonSymbol
AsBsonTimestamp
AsBsonUndefined
AsByteArray (=> byte[])
AsDateTime (=> DateTime)
AsDouble (=> double)
AsGuid (=> Guid)
AsInt32 (=> int)
AsInt64 (=> long)
AsNullableBoolean (=> bool?)
AsNullableDateTime (=> DateTime?)
AsNullableDouble (=> double?)
AsNullableGuid (=> Guid?)
AsNullableInt32 (=> int?)
AsNullableInt64 (=> long?)
AsNullableObjectId (=> ObjectId?)
AsObjectId (=> ObjectId)
AsRegex (=> Regex)
AsString (=> string)
It is important to note that these all are casts, not conversions. They will throw an InvalidCastException if the BsonValue is not of the corresponding type. See also the To[Type] methods which do conversions, and the Is[Type] properties which you can use to query the type of a BsonValue before attempting to use one of the As[Type] properties.

Sample code using these properties:

    BsonDocument document;
    string name = document["name"].AsString;
    int age = document["age"].AsInt32;
    BsonDocument address = document["address"].AsBsonDocument;
    string zip = address["zip"].AsString;
Is[Type] Properties

BsonValue has the following boolean properties you can use to test what kind of BsonValue it is:

IsBoolean
IsBsonArray
IsBsonBinaryData
IsBsonDocument
IsBsonJavaScript
IsBsonJavaScriptWithScope
IsBsonMaxKey
IsBsonMinKey
IsBsonNull
IsBsonRegularExpression
IsBsonSymbol
IsBsonTimestamp
IsBsonUndefined
IsDateTime
IsDouble
IsGuid
IsInt32
IsInt64
IsNumeric (true if type is Double, Int32 or Int64)
IsObjectId
IsString
Sample code:

    BsonDocument document;
    int age = -1;
    if (document.Contains["age"] && document["age"].IsInt32) {
        age = document["age"].AsInt32;
    }
To[Type] conversion methods

The following methods are available to do limited conversions between BsonValue types:

ToBoolean
ToDouble
ToInt32
ToInt64
The ToBoolean method never fails. It uses JavaScript's definition of truthiness: false, 0, 0.0, NaN, BsonNull, BsonUndefined and "" are false, and everything else is true (include the string "false").

The ToBoolean method is particularly useful when the documents you are processing might have inconsistent ways of recording true/false values:

    if (employee["ismanager"].ToBoolean()) {
        // we know the employee is a manager
        // works with many ways of recording boolean values
    }
The ToDouble, ToInt32, and ToInt64 methods never fail when converting between numeric types, though the value might be truncated if it doesn't fit in the target type. A string can be converted to a numeric type, but an exception will be thrown if the string cannot be parsed as a value of the target type.

Static Create methods

Because BsonValue is an abstract class you cannot create instances of BsonValue (only instances of concrete subclasses). BsonValue has a static Create method that takes an argument of type object and determines at runtime the actual type of BsonValue to create. Subclasses of BsonValue also have static Create methods tailored to their own needs.

Implicit conversions
Implicit conversions are defined from the following .NET types to BsonValue:

bool
byte[]
DateTime
double
Guid
int
long
ObjectId
Regex
string
These eliminate the need for almost all calls to BsonValue constructors or Create methods. For example:

    BsonValue b = true; // b is an instance of BsonBoolean
    BsonValue d = 3.14159; // d is an instance of BsonDouble
    BsonValue i = 1; // i is an instance of BsonInt32
    BsonValue s = "Hello"; // s is an instance of BsonString
BsonMaxKey, BsonMinKey, BsonNull and BsonUndefined

These classes are singletons, so only a single instance of each class exists. You refer to these instances using the static Value property of each class:

    document["status"] = BsonNull.Value;
    document["priority"] = BsonMaxKey.Value;
Note that C# null and BsonNull.Value are two different things. The latter is an actual C# object that represents a BSON null value (it's a subtle difference, but plays an important role in functional construction).

ObjectId and BsonObjectId

ObjectId is a struct that holds the raw value of a BSON ObjectId. BsonObjectId is a subclass of BsonValue whose Value property is of type ObjectId.

Here are some common ways of creating ObjectId values:

var id1 = new ObjectId(); // same as ObjectId.Empty
var id2 = ObjectId.Empty; // all zeroes
var id3 = ObjectId.GenerateNewId(); // generates new unique Id
var id4 = ObjectId.Parse("4dad901291c2949e7a5b6aa8"); // parses a 24 hex digit string
Note that the first example behaves differently in C# than in JavaScript. In C# it creates an ObjectId of all zeroes, but in JavaScript it generates a new unique Id. This difference can't be avoided because in C# the default constructor of a value type always initializes the value to all zeros.

BsonElement
A BsonElement is a name/value pair, where the value is a BsonValue. It is used as the building block of BsonDocument, which consists of zero or more elements. You will rarely create BsonElements directly, as they are usually created indirectly as needed. For example:

    document.Add(new BsonElement("age", 21)); // OK, but next line is shorter
    document.Add("age", 21); // creates BsonElement automatically
BsonDocument
A BsonDocument is a collection of name/value pairs (represented by BsonElements). It is an in-memory object model of a BSON document. There are three ways to create and populate a BsonDocument:

Create a new document and call Add and Set methods
Create a new document and use the fluent interface Add and Set methods
Create a new document and use C#'s collection initializer syntax (recommended)
BsonDocument constructor

BsonDocument has the following constructors:

BsonDocument()
BsonDocument(string name, BsonValue value)
BsonDocument(BsonElement element)
BsonDocument(Hashtable hashtable)
BsonDocument(Hashtable hashtable, IEnumerable<string> keys)
BsonDocument(IDictionary<string, object> dictionary)
BsonDocument(IDictionary<string, object> dictionary, IEnumerable<string> keys)
BsonDocument(IEnumerabe<BsonElement> elements)
BsonDocument(params BsonElement[] elements)
BsonDocument(bool allowDuplicateNames)
The first two are the ones you are most likely to use. The first creates an empty document, and the second creates a document with one element (in both cases you can of course add more elements).

All the constructors (except the one with allowDuplicateNames) simply call the Add method that takes the same parameters, so refer to the coresponding Add method for details about how the new document is initially populated.

A BsonDocument normally does not allow duplicate names, but if you must allow duplicate names call the constructor with the allowDuplicateNames parameter and pass in true. It is not recommended that you allow duplicate names, and this option exists only to allow handling existing BSON documents that might have duplicate names. MongoDB makes no particular guarantees about whether it supports documents with duplicate names, so be cautious about sending any such documents you construct to the server.

Create a new document and call Add and Set methods

This is a traditional step by step method to create and populate a document using multiple C# statements. For example:

    BsonDocument book = new BsonDocument();
    document.Add("author", "Ernest Hemingway");
    document.Add("title", "For Whom the Bell Tolls");
Create a new document and use the fluent interface Add and Set methods

This is similar to the previous approach but the fluent interface allows you to chain the various calls to Add so that they are all a single C# statement. For example:

    BsonDocument book = new BsonDocument()
        .Add("author", "Ernest Hemingway")
        .Add("title", "For Whom the Bell Tolls");
Create a new document and use C#'s collection initializer syntax (recommended)

This is the recommended way to create and initialize a BsonDocument in one statement. It uses C#'s collection initializer syntax:

    BsonDocument book = new BsonDocument {
        { "author", "Ernest Hemingway" },
        { "title", "For Whom the Bell Tolls" }
    };
The compiler translates this into calls to the matching Add methods.

A common mistake is to forget the inner set of braces. This will result in a compilation error. For example:

    BsonDocument bad = new BsonDocument {
        "author", "Ernest Hemingway"
    };
is translated by the compiler to:

    BsonDocument bad = new BsonDocument();
    bad.Add("author");
    bad.Add("Ernest Hemingway");
which results in a compilation error because there is no Add method that takes a single string argument.

Add methods

BsonDocument has the following overloaded Add methods:

Add(BsonElement element)
Add(Hashtable hashtable)
Add(Hashtable hashtable, IEnumerable<string> keys)
Add(IDictionary<string, object> dictionary)
Add(IDictionary<string, object> dictionary, IEnumerable<string> keys)
Add(IEnumerable<BsonElement> elements)
Add(string name, BsonValue value)
Add(string name, BsonValue value, bool condition)
It is important to note that sometimes the Add methods don't add a new element. If the value supplied is null (or the condition supplied in the last overload is false) then the element isn't added. This makes it really easy to handle optional elements without having to write any if statements or conditional expressions.

For example:

    BsonDocument document = new BsonDocument {
        { "name", name },
        { "city", city }, // not added if city is null
        { "dob", dob, dobAvailable } // not added if dobAvailable is false
    };
is more compact and readable than:

    BsonDocument document = new BsonDocument();
    document.Add("name", name);
    if (city != null) {
        document.Add("city", city);
    }
    if (dobAvailable) {
        document.Add("dob", dob);
    }
If you want to add a BsonNull if a value is missing you have to say so. A convenient way is to use C#'s null coalescing operator as follows:

    BsonDocument = new BsonDocument {
        { "city", city ?? BsonConstants.Null }
    };
The IDictionary overloads initialize a BsonDocument from a dictionary. Each key in the dictionary becames the name of a new element, and each value is mapped to a matching BsonValue and becomes the value of the new element. The overload with the keys parameter lets you select which dictionary entries to load (you might also use the keys parameter to control the order in which the elements are loaded from the dictionary).

arrow
arrow
    全站熱搜

    weihsinchiu 發表在 痞客邦 留言(1) 人氣()