Posted on 1/19/2008 4:22:00 PM by Justin Etheredge
Update: This project is up over at Codeplex.
If you follow this blog then you probably know that I am working on a Linq To SimpleDB provider. I finally have it doing something, and so I wanted to post up a preview here in order to potentially get a little feedback.
First of all I wanted to mimic the way that Linq To SQL works, in that I have a context which basically uses a unit of work pattern in order to track changes made to SimpleDB items and allows you to save them back to the database. This context object also allows you to perform other non-query tasks on the database. For instance, if you wanted to try and create a domain, you would do it like this:
SimpleDBContext.SetAccessKeys("testKey", "testKey");
SimpleDBContext.CreateDomain("TestDomain");
The call to "SetAccessKeys" sets up a static set of keys that can be used throughout the application. This makes it so that you don't have to pass in your access key and secret key every time. So we are just setting keys and calling "CreateDomain" and that is it. Domain created!
Next we can also do the same thing to delete a domain:
SimpleDBContext.DeleteDomain("TestDomain");
So, there goes our domain. So, lets pretend that we didn't delete our domain and lets go ahead and populate the domain with a little bit of data. First we are going to need to setup a new context object:
SimpleDBContext context = SimpleDBContext.GetContext("TestDomain");
After we setup our new context we are going to need to create some new items to put in it. Here is how we can create a new item and put some attributes into it, then add it to the context:
var item = new LinqToSimpleDB.SimpleDBItem("Item1")
.WithAttribute("AttributeName1", "value1", "value2")
.WithAttribute("AttributeName2", "value3", "value4");
context.AddItem(item);
Then all we have to do is submit the changes back to the database.
This call will go through all of the items that you have added and submit them to the database. It will also remove any items that you may have deleted. This is how you remove an item:
context.RemoveItem(item);
This will mark the item as deleted so that when you call "SubmitChanges" it will be removed from the database (assuming that it has already been saved to the database) Next, lets look at how to query this data back out of SimpleDB. We just use the context object and we query like this:
var items = from p in context.Domain where
p.Attributes["attrib1"] == "value1" select p;
This will get us our expression tree that we can then execute by calling something like "ToList" or putting it in a "foreach" statment. So here we see us executing our query by running it through a "foreach" statement and checking to make suer that we got our item back.
foreach (SimpleDBItem dbItem in items)
{
if (dbItem.Name == "Item1")
{
return true;
}
}
I also have the "Union" and "Intersect" parts of the SimpleDB query spec working now, and these just use the built in Union and Intersect operators provided by Linq. A Union would look like this:
var items = (from p in context.Domain
where
p.Attributes["attrib1"] == "value1"
select p)
.Union(from p in context.Domain
where
p.Attributes["attrib2"] == "value3"
select p);
I don't have the lazy loading on these queried items done yet (since SimpleDB only returns item names and not the associated attributes), but everything you have seen here is working so far. I am also doing a bit more work with storing numbers in SimpleDB, there is definitely a bit of work that you have to do since Amazon stores everything as text. I am also a bit torn on supporting any kind of query projections, not only is it a pain to do so, but I would have to lazy load every item in order to do a projection, since SimpleDB does not provide a mechanism for pulling back bulk attributes for numerous items.
But for now, I wanted to try and get a little feedback on how this looks so far, and I hope to have an early release out sometime soon.