Now that we have a model built over the Chinook database tables, the next step to take is to build a domain service that exposes those entities to the client tier (as I mentioned in my previous post.) The RIA services team encourages you to do this in the Services folder of the server-side project, so I did just that by adding a new item and using the Domain Service Class web template as shown:
I was then asked which entities I wanted to expose. As there are lots of foreign keys across these tables, I chose them all, but was more selective about which I enabled for editing (i.e., only those for which I really need it.) Also, I checked “Generate associated classes for metadata” because this comes in handy for doing declarative validation via the DataAnnotations attributes which RIA uses so nicely.
This adds 2 files to the Services folder as shown (TwelveDaysOfRiaService.cs and TwevleDaysOfRiaService.metadata.cs), and it’s worthwhile to walkthrough both.
In TwelveDaysOfRiaService.cs, you’ll see something like the following (I removed a few comment blocks and CR/LFs so I could show more):
The service itself extends the base LinqToEntitiesDomainService<TwelveDaysOfRiaEntities>, is marked to [EnableClientAccess()], and contains a public GetXxx method which returns an IQueryable<T> for each entity I added to the service. For those which I checked enable editing, the InsertXxx, UpdateXxx, and DeleteXxx methods were generated.
The TODO: comments appearing above the GetXxx methods are being gentle – they should be strongly considered or perhaps even obeyed. The reason is that by default they return the entire collection of the entity in question:
This of course can be problematic when that collection grows large. We’ll deal with that a little later on, but for now, I’m going to add sorting logic to each so that they’re consumable by the DataPager control on the client side (will show what happens when you don’t sort when we get there.) To each GetXxx method, I added an OrderBy and picked an appropriate column.
I’ll discuss the InsertXxx, UpdateXxx, and DeleteXxx methods when we get to that part of the client side.
The metadata file (TwelveDaysOfRiaService.metadata.cs) is quite interesting. It contains one class for every entity in the service, and it also contains metadata nested on a class within each (as the comments explain so nicely):
The MetadataTypeAttribute lets the compiler know which type contains the metadata for this class (following the pattern Xxx.XxxMetadata), and the attributes mentioned in the second comment block all live in the System.Component.DataAnnotations namespace, which conveniently is present in both Silverlight and the full versions of the .NET Framework.
This class is marked partial, and this part only contains the nested metadata class. I marked the Album’s Title as required with a maximum string length of 160 (as per the database schema) as shown:
We’ll see these attributes in action when we get to validation.
So where’s the other part of this partial class? At the bottom of the graphic above are the results of a right-click “Go To Definition” for Album. The other part of this class was generated when we added the model, and it lives in TwelveDaysOfRiaModel.Designer.cs (under the .edmx file.)
Notice that the setters for the properties are calling out to some partial methods and are providing some notifications before and after changing the value.
This may seem complicated, but it’s essential for almost every non-trivial line of business app I’ve encountered.
Now that we have a model and a domain service, the next step is to make use of it up on the client, and that the subject of my next posting.
Meanwhile, code for Day 3 is posted here.