Business Apps Example for Silverlight 3 RTM and .NET RIA Services July Update: Part 10: LinqToSql


Continuing in our discussion of Silverlight 3 and  the update to .NET RIA Services.  I have been updating  the example from my Mix09 talk “building business applications with Silverlight 3”.


You can watch the original  video of the full session


The demo requires (all 100% free and always free):



  1. VS2008 SP1 (Which includes Sql Express 2008)

  2. Silverlight 3 RTM

  3. .NET RIA Services July ’09 Preview

Also, download the full demo files and check out the running application.


I was very surprised recently when someone mentioned that RIA Services only worked with Entity Framework.  That is of course not true, but then I realized that we have not been demoing it with LinqToSql nearly enough.   So I thought I’d update my demo app to use LinqToSql rather than Entity Framework.


There are lots of reasons you might be using LinqToSql.. Some folks have found it lighterweight and easier to moch making testablity more simple.  Others standardized on it for a project and others just prefer it.  Either way, RIA Services works great with LinqToSql.


image


Let’s switch over the example application to use LinqToSql.  First let’s add a new edmx..



image


And drag the SuperEmployee table over..


image


Save and build!


Now we make some very minor changes to the SuperEmployeeDomainService..


 



   1: [EnableClientAccess()]
   2: public class SuperEmployeeDomainService : LinqToSqlDomainService<SuperEmployeeDataContext>
   3: {
   4:  
   5:         public IQueryable<SuperEmployee> GetSuperEmployees()
   6:         {
   7:             return this.Context.SuperEmployees
   8:                        .Where(emp=>emp.Issues>100)
   9:                        .OrderBy(emp=>emp.EmployeeID);
  10:         }

No changes to the client at all..   Build hit F5 and the app runs


Notice in line 2, we are using the LinqToSqlDomainService as a base class rather than the EntityFrameworkDomainService.


In line 7, notice that nothing changes here.. the power of Linq!


That is really all we had to do… hit F5 and the main Silverlight App we were building keeps working..


image


And all the other goodness just keeps working as well… let’s revisit them all just to remind ourselves how cool RIA Services is 😉


The ASP.NET page that is our sitemap


image


The ASP.NET page that renders downlevel\SEO content


image


The ADO.NET Data Services (Astoria) REST based view


image


And of course, the WinForms view


image

Comments (10)

  1. Bryan G Campbell says:

    Brad,

      This has been a great series.  By far the most informative about .NET RIA Services and on a level I can still understand ;-).  Especially this Linq to SQL, thank you as that’s what I’m using for unit testing purposes.

      I have two questions regarding .NET RIA Services that I’ve yet to see answered anywhere.  I thought it may be good for this series and wanted to know what you think.

      1)   How does the .NET RIA Services tools deal with changes to the database?  If as I’m going along in my development I decide I need to add a new column to a database table, how can I get my .edmx or .dbml to pick up this change?  If I decide to add in a new table, what’s the best way to add this into my DomainService?  The heart of this question is getting at .NET RIA Services being great for RAD but I’d like to see how if performs in the application update/maintenance phase.

      2)   What is the best way to deal with a large number of tables?   If I bring them into one .edmx or .dbml it will be huge, is that okay?  What about the DomainService?  Should it be split out using partial classes?  But it’s auto generated code so if I change anything I’ll have lost all that work.

      Any guidance would be appreciated.

  2. BradA says:

    Bryan G Campbell  – Great.. I am glad you are enjoying the series.. I am too!  And I am learning a ton along the way..

    The evolution question is a good one.. .one that could be another whole post.  The short answer is that it is up to the DAL.. If you add a new column then, you need to update your model.  In entity framework, there is an “update from Database” context menu that you can do a table at a time.. If you add a while new table, this can easily be added to the  model just by using the wizard or dragging it out from server explorer.   Once the model is updated the client types will also be updated, so all you should need to do is add some binding code to the UI to start showing the new data…  When a new table is added, you will need to add the appropriate methods to the DomainService to query and update those new tables. Once that is done, the new type will be accessible to the client and you can bind away.

    I have heard several people ask about the best practice on factoring your DomainService.. The way I think about this is that you want one DomainService per “screen” in your client UI.. for example if you have a screen for dealing with orders and another suppliers, then I’d suggest factoring those into two different DS classes..  The other thing to think about is what is the unit of work in your application?  Do you need to update table X and Y in the same batch, if so, maybe those should be in the same DS..  

    Hope that helps!

  3. jeangab says:

    Hi,

    To continue on question #2, maybe the solution could be to have a domainService per Use Case. This way your UML model could have is counterpart in the code and maintaining both models and code could be easier…

    JeanGab

  4. Bryan G Campbell says:

    @Brad,

      Thanks for the response, very helpful. I’ve been trying to implement Test Driven Development in this .NET RIA Services world.  Thanks to your feedback as well as a post on Vijay’s blog called "Unit Testing Business Logic in .NET RIA Services" I believe I have a better handle on how to do this.  I’m sure my approach will continue to evolve, but at least I have a starting point.

      @JeanGab – Thanks for the input. It’s always great to get additional perspectives on a problem, helps me break out of my tunnel vision.

    Bryan

  5. BradA says:

    JeanGab – Yup a "use case" seems like a good way to think about this..  

  6. Ozzy says:

    Brad,

    Thanks for this series — very useful!

    I would like to see some additional guidance on how best to use RIA with Prism.

    Ozzy

  7. BradA says:

    Ozzy – Yup, I have been talking to the Prism folks about a sample and I think that is on the radar.. stay tuned!

  8. Hi Brad!

    How can we determine the total of items of DomainDataSource ?

    I would like to display in a text box the number of records of the database (next to the pager of the grid), so the user would have an idea of the size of data.

    Thanks,

    Rachida Dukes

  9. Hi Brad,

    I have troubles deleting an item with LinqToSql. In the delete method I have the following code:

    this.Context.Questions.Attach( q );

    this.Context.Questions.DeleteOnSubmit( q );

    where q is a Question object.

    The object is deleted from the db, but the DataGrid bound to the DomainDataSource is not updated correctly. I can see that the item disappears from the DataGrid at first, but in the next moment it is shown again. If I reload the page, thus causing the DomainDataSource to load the data again, the item is deleted.

    In XAML I have the exact same case as in your demo: DDS set as ItemsSource to both DataGrid and DataForm, DataForm’s CurrentItem is bound to DataGrid’s SelectedItem. I handle the DataView.CollectionChanged event of the DDS and in case the Action is Remove I call SubmitChanges().

    Thanks!

  10. Mark Salsbery says:

    Hi Emil,

    I stumbled across this page while looking for a fix for the same issue, except in my case, a ListBox is the master view.  The deleted record moves to the end of the list, and trying to delete it again gives WSOD.

    For me, calling myDomainDataSource.Load(); after the SubmitChanges() call in the CollectionChanged event handler seems to fix it.

    I still get artifacts in the listbox sometimes if I cancel an Add operation, however.

    Cheers,

    Mark

    Microsoft MVP – Visual C++