Even with NoSQL, having a repository layer is a good idea. In the world of DocumentDB, writing this layer is really simple. First, we’ll start with an interface, of course. In your application, this interface might already exist.
public interface IEquipmentRepository
{
IEnumerable<Equipment> GetEquipments();
Equipment GetEquipmentById(string id);
Equipment AddEquipment(Equipment equipment);
Equipment UpdateEquipment(string id, Equipment equipment);
void DeleteEquipment(string id);
}
As, you can see, this is a pretty straight-forward interface with CRUD (Create-Read-Update-Delete) operations. Notice that the identifier is a string, not an integer like you might be used to seeing. DocumentDB, like other document databases, likes the identifier to be a GUID. Don’t try to make it the .NET GUID type. Just go with string, and then the database will handle it just like SQL does with integer identifiers.
If you’re following along in your own code, you’ll need the Equipment model. Here’s a snapshot of what it looked like when this post was written: Equipment.cs.
The next thing would be to implement the repository, but before you do that you’ll need a couple of extension methods to make your life easier. You can find them in my previous post on getting existing databases and collections. Do that, and then come back. I’ll be right here. You can also look at the source for the whole project, using the link at the bottom.
You’re going to need two fields in your repository: the DocumentClient and the Document Link. This is how I’m getting them at the time I write this. It isn’t optimal, but I have plans for more posts about making that better and those topics are beyond the scope of this post. So here it is:
private static readonly DocumentClient Client =
new DocumentClient(new Uri(<Your Url>), <Your Key>);
private static readonly string DocumentLink =
Client.GetOrCreateDocumentCollectionAsync("dmart", "equipment")
.Result.DocumentsLink;
Now that we have those, let’s implement the first method, GetEquipments. There’s not much to it, but there’s a lot to talk about:
public IEnumerable<Equipment> GetEquipments()
{
return Client.CreateDocumentQuery<Equipment>(DocumentLink)
.AsEnumerable();
}
This method uses the DocumentClient we created as a field. It calls the CreateDocumentQuery<T> method to query the document collection referenced by the DocumentLink (our other field).
Notice that the method returns an IEnumerable<T> and not a List<T>. What this means is that when the method returns, we haven’t actually queried the collection. We’re putting that off until later to allow the caller to filter on the IEnumerable. This makes the usage of our get list method more flexible, and possibly saves us from unnecessarily passing a huge collection across the wire.
However, in some cases there will be a way of filtering that is so common we’re just going to provide the users of our class a built in method for that. The seminal example would be wanting to get an Equipment by it’s identifier. For that, we’ll implement the next method.
public Equipment GetEquipmentById(string id)
{
return Client.CreateDocumentQuery<Equipment>(DocumentLink)
.AsEnumerable().First(d => d.id == id);
}
It looks a lot like the last method, except that it filters and returns a single Equipment object. Notice that I’m using First instead of FirstOrDefault, which will throw an exception if the Equipment with that guid doesn’t exist. Since a guid is a really hard key to fake, I don’t expect that will happen much and an exception is probably appropriate. I might regret that decision later.
That’s it for reading from your DocumentDB collection. In my next post, I’ll go over the remaining write methods.
The code used for this post lives here:
https://github.com/qanwi1970/dungeon-mart/tree/3ad6081b36b5fc804b0c6dce03daa1a2699edd87
Continue with the writing methods in Part 2.
Update: The code when I published was missing the .AsEnumerable() in the GetEquipmentById method. Sorry about that. By the time I found and fixed it, the code had moved on and would just be confusing to point to, now.
Pingback: Creating a DocumentDB Repository Layer (Part 2 – Writing) | Bill DeLude
Reblogged this on Coding, Unix & Other Hackeresque Things.
Pingback: Refactoring My Repository Methods to be Asynchronous | Bill DeLude