Nice new features

Hot onto NuGet now, Simple.Data 0.6.6 has a couple of nice new features to make life even easier.

Cleverer type handling in Simple.Data.Ado

The Ado adapter now tries much harder to make the data that it is given work with the underlying provider. In practice, this means that it will check to see whether the value is a “known-good type”, and if it’s not, it will try calling “ToString” to see if it returns something other than the type’s full name; if it does, it will pass that string. This means that, amongst other things, you can pass the dynamic values from Nancy’s Request objects across without casting them. So technically, you can now say

[sourcecode language="csharp"]

db.Comments.Insert(Request.Form)

[/sourcecode]

although I wouldn’t recommend it.

Child rows returned as Query

Up to now, if you used the inferred detail property feature in Simple.Data, what you got from that property was an IEnumerable<dynamic>. Now, you get a SimpleQuery, which means you can do filtering, ordering and so on on those detail rows.

This feature means that the query comes pre-created with some criteria, so I’ve changed the way the Where method works (still in beta, I’m allowed). Now, Where will combine any existing criteria with the specified criteria. If you want to completely replace any existing criteria, use the new ReplaceWhere method.

ToScalarOrDefault

I don’t think I mentioned this last time, but there is now a SimpleQuery.ToScalar method which, as long as your query returns one row with one column, will return that single value. If there is not exactly one row, an exception will be thrown. 0.6.6 adds ToScalarOrDefault, which will return null if no row was found, and ToScalarOrDefault<T>, which returns default(T).

Detail properties on Queries

By “detail properties” I mean those properties on records returned from Simple.Data which execute a further query on the database and return detail (or master) records. These are now available on SimpleQuery objects, so you can say:

[sourcecode language="csharp"]

db.Customers.QueryByTown(“London”).Orders.Count();

[/sourcecode]

for example. This code runs only one command against your database; the Orders pseudo-property returns a new query which incorporates the criteria from the original Customers query. Thus your DBA is happy, because you are not doing that SELECT N+1 thing he/she hates so much. (Of course, if they’d just upgrade the server to that one with a PCI-e SSD array it wouldn’t matter anyway. But no. So here we are.)

An aside on writing APIs

If you check the commit history for Simple.Data, you’ll see that I implemented that last change twice. The first time I did something super-awesome with “rebasing” expressions and object references, and it all worked as if by magic. But then on the drive home, I realised that (a) that was the hard way, and (b) it hides too much information from adapter authors, who might be implementing this kind of functionality in a totally different way. So I re-implemented it in a much more obvious way, which also included a bit of much-needed refactoring, and it all works as it should and adapter authors won’t hate me any more than they already do.

That’s it for Simple.Data coding for this week; I’ve got to polish up my demo apps for DDD South West this weekend. The same mini-app created twice: once in WebMatrix with the data access layer that started all this; and once in Nancy using Simple.Data. Guess which one’s better.