Protected: OC

This content is password protected. To view it please enter your password below:

Advertisements
Posted in RIA, WCF | Enter your password to view comments.

RIA WCF services: Domain Services and query cost on the database

From the Northwind database, I’ve generated an entity model consisting of the Orders table. For the domain service, right now, I just have an unconstrained table scan, which of course you would never do in practice. This is generated code:

DomainService01

DomainService02

If we pass in this query from the Domain Context:

DomainService06

, then this is what we see in SQLProfiler, as expected (well, all of it’s as expected):

DomainService05

That is, there is no restriction or sorting on the query.

What if we add a sort to the query, for example:

DomainService04

This is what we get in Profiler, again, as expected, in that our OrderBy has been executed on the database server:

DomainService03

However, what you cannot tell from Profiler is the query plan.

(actually, that’s not true: digging around SQL profiler for the plan is just not much fun if you have the realtime facts to hand as an alternative)

.For that, copy and paste the text into SSMS:

DomainService07

It has to plough through the whole of the table anyway, but it is made more inefficient by the fact that ShipCity is not an indexed column. Let’s compare that plan with one where the Order By is on an indexed column – we’ll use OrderId, which is the PK column:

DomainService08

The big difference is that when you sort by ShipCity, SQL has to add in a sort operation, whereas when you sort by OrderId, because the key is clustered around that column already, then it is already in the right order.

Comparing the relative performance and cost of the 2 queries (if you didn’t know, just run both queries in the same SSMS windows):

DomainService09

As we already knew, the sort operation more than doubles the cost.

If you want to follow the database example, see my links here about Northwind.

WCF RIA services – Convention based CRUD operations

1 of obviously a number of posts on MSDN on Domain Services:

msdn01

I was going through this Pluralsight course on RIA services, entering the examples in by hand. In 1 example, there was a domain service class with a query method, and an update method. I wanted to be clear on 1 thing at a time, so I just did the query method to start with. This was against a Singleton implementation of a set, for what that’s worth.

So the query went fine (other than the issues re path length, for which I’ve yet to categorically prove the cause). I then moved to a section where 2 datagrids were each instantiating their own copy of the domain context. The idea was that you changed a value in one DataGrid, ran SubmitChanges(), and then refreshed the other grid, getting the just-saved change back from the server, such that the change was reflected in both grids.

Now, accepting that I had only implemented the Query part of the Crud set, I just noted that I got this error when moving from 1 row to another following a change (but before  sending SubmitChanges()):

UpdateError01

 

But given I hadn’t implemented the update, that kind of didn’t surprise me. But when I looked at the Domain Service code for the update, I could not see how it related to the SubmitChanges() action:

    public void UpdateComposer(Composer composer) {
	data.Update(composer);
    }

… particularly when the data model method looks like this:

public void Update(Composer composer) {
			var current = _composerList.Find(p => p.ComposerId == composer.ComposerId);

			if (current == null) {
				throw new KeyNotFoundException("No Composer found with that key");
			}

			current.Fname = composer.Fname;
			current.Lname = composer.Lname;
			current.BirthDate = composer.BirthDate;
			current.AgeAtDeath = composer.AgeAtDeath;
		}

So I then implemented the above 2 Update methods. You only need to know that it worked, but I was puzzled that it had found its way to the apparently arbitrarily named UpdateComposer method. I then changed the name of that Domain Service method to UpdateXComposer. It still worked. I then changed it UpdatXeComposer.

This time it allowed me to move from 1 row to the next in the grid, but when I tried to SubmitChanges, I got this message:

UpdateError02

So this means that RIA services, is just looking for any old method that starts with Update. In fact trying a nonsense name, it still hits the breakpoint:

UpdateError03

What happens if I then duplicate the method, but given one a different name? Compile-time error:

UpdateError04

So they at least tested it. 🙂

And on an unrelated point, this is the compile error you get if you forget to decorate your key field in your data class with a [key] attribute, ie if you fail to do this:

public class Composer {
    [Key]
     public int ComposerId { get; set; }

UpdateError05

Coming back to the use of a nonsense string in the method name, let’s focus on the name, or part name, as seems to be significant, of the method, prove (again) that it works as-is, and then look for the string in a decent text editor from the root of the solution down.

Here is the Domain Service method, again, this time with the surely unique on my PC string in the name [stuffx]:

stuffx01

Prove it works:

stuffx02

Yes. I edited Haydn to become Haydnx, and it was saved back to the server.

Now we look for the string from the solution root down:

stuffx03

 

In 1 non-compiled location only. So clearly some convention-based, inference-based compilation going on. Fine.