Just published the latest Simple.Data build to NuGet with both the above versions (the 0.x versions get patched more often, generally the –pre packages are updated with a minor version bump, like 0.17 to 0.18). We’re really nearly at 1.0 now, just fixing the last few issues and getting the docs finished (Dan Maharry is doing a bang-up job on those).
I’ve had a couple of feature requests that have been outstanding for a very, very long time now: the ability to specify a command timeout; and a way to do “identity inserts” in SQL Server (that’s where you override a table’s identity column specification and supply your own values).
Both these features are kind of specific to ADO, so I didn’t want to implement them in a way that affected other adapters like MongoDB or OData. At the same time, I wanted to allow those adapters to have their own customisation options. I also didn’t want to make enormous changes to the code to support these features: if a command timeout were added as an optional parameter to the various “methods”, I’d have had to go through adding code in dozens of places.
So here how you want to insert a record into a SQL Server table, with an identity override, and a command timeout of 1 second:
db.WithOptions(new AdoOptions(commandTimeout: 1, identityInsert: true)) .Users.Insert(Id: 42, Name: "Marvin", Occupation: "Android");
db.Users.Insert(Name: "Eddie", Occupation: "Shipboard Computer");
Let me explain what happens there.
When you call WithOptions, a shadow copy of the underlying Database (or Transaction) object is created, with a shadow copy of the Adapter, and the options are set on that copy. So the first call to Users.Insert happens on that shadow copy, and the second call happens on the original, which doesn’t have those options set.
Somebody told me they thought having the options at that point in the call chain was clunky, but there are a couple of reasons for it being there; one technical, and one API design.
The technical reason is that putting it anywhere else is either difficult or impossible. I thought about putting it on the table object instead of the database, but that wouldn’t work for stored procedures, which are a common case for needing to set a longer timeout period. And it can’t go at the end of the call chain, because most methods return directly, so you can’t chain anything onto them.
The design reason is that this way allows you to create a reusable database object with options set, which strikes me as being potentially very useful. Maybe you want all commands executed against the database to have a shorter timeout than the default 30 seconds. In that case, you only need to set the options once, on a database object held in a field in a type, and then all your calls happen with those settings. Also, I can envisage other future uses for this Options-based approach, other options that might be database-wide, so putting the WithOptions call there leaves maximum scope for those future options.
I fixed a bunch of small-to-medium problems in this release, too. There was an issue with the way I was scanning assemblies and using MEF to compose adapters and providers which is now fixed. I’ve also fixed a problem with the magic casting in medium trust environments, and a handful of problems people reported on GitHub. There are still a couple of issues outstanding, which will get fixed in a 0.18.x patch soon, and then I sincerely hope there’ll be a short RC2 period before the long-awaiting 1.0 final release. Not least because there’s a 1.5 that I really want to get on to, adding async support.
I’d like to thank everyone who has helped with this release, either with pull requests, or bug reports, diagnostic efforts and patience, or in one instance somebody who gave an excellent answer to a really obscure question on Stack Overflow. I can’t call out everybody, but you are all appreciated.