Hi Johan,
When I get a moment I'll try and organise some sort of documentation, though it would be useful if someone were prepared to translate samples in C# into XSharp for that. If XSharp had appeared a few years earlier I would undoubtedly have used it, but of course like many others I just couldn't wait for Vulcan to get it's act together so had to make the jump to C#. Having said that, as I've mentioned before, I now love the clarity given by curly braces and semi-colons.
In SQL Server you have the Rowver byte[] column which is specifically designed for concurrency control (it is incremented automatically with each update to the record). With Entity Framework all you have to do is include a Rowver type column in your table and EF will automatically use it for concurrency control - if the record you're trying to save has a different Rowver value than the record in the db, a concurrency exception is thrown.
PostgreSQL doesn't have this. What it does have is a hidden system column called xmin of type uint which is automatically added to every table, and which is also incremented automatically with each update of the record. The Npgsql EF provider has an option to switch on the use of this column for concurrency control which then gives you the same effect as the Rowver column.
The trouble arises with a disconnected environment like ours. If you access the database directly using EF from your client application, then it's very easy. In pseudo code:
Code: Select all
company = mydatabase.Companies.Where(c => c.Name == "Trump Inc").SingleOrDefault();
company.Address = "Red Square";
mydatabase.SaveChanges();
If the company record gets changed by another user in the meantime, a concurrency exception is thrown and you can then handle it however you want. However this implies referencing EF throughout the application, which violates all principles of separation of tiers. So we map the objects returned by EF to in-memory objects disconnected from EF. To handle the concurrency with SQL Server we just include the Rowver column in the in-memory objects and round-trip it to the client. With PostgreSQL though we have to lever out the hidden xmin column and round trip that - luckily the Npgsql provider has options to allow this.
With regard to snake case, this is a real pain as of course C# is case sensitive and I like camel case for my class properties. If you do that though and generate a database in PostgreSQL, as soon as you capitalise anything in PG you have to enclose it in double quotes in raw sql. So this means escaping quotes all over your statements which is a real pain and of course very subject to errors. The trick is to force EF to map all the class and property names related to the db into lower case and let the automatic mapping to/from the database handle the conversion to the in-memory camel case equivalents.
Ho hum!
Nick