WPF and MVVM tutorial 02, The model.

In the first part of this tutorial we saw the MVVM model and how it works.

In this part of our tutorial we will work directly with the Entity Model and LinqToSQL. I am using a database-first approach so in my opinion using LinqToSQL will be better then Entitiy Framework. I am going also to show you an easy way to build a custom Unit Of Work to manage the context status with Linq 2 SQL.

The Visual Studio Project.

First of all open a blank Visual Studio solution, I called it WPF.Tutorial.VMMV. Add two projects on it: 1) WPF Application …UI and 2) Class Library (…DAL).

The final layout should be this one (in my picture the model is already inside).

New Picture (8)

The Data model.

If you have installed the Adventure Works database in the past you already know what I am talking about. The model I will use in the tutorial will come up with this layout:

New Picture (7)We will have a customer with the personal information and the related orders with the order information.

Go into the DAL project and from the menu choose add new file –> LinqToSQL and call it DataModel. Now you need to connect you data model into your AW database and drag in the design pane the tables you need. At the end you should come up with the same layout I have in the previous picture.

The Unit of Work.

If you do not what I am talking about, this is the explanation by Martin Fowler.

A Unit of Work keeps track of everything you do during a business transaction that can affect the database. When you’re done, it figures out everything that needs to be done to alter the database as a result of your work.

Of course with LinqToSQL we do not need a Unit of Work because L2S by itself is the data context, but because it is not able to manage the disposing in a good way, here are my 2 cents about.

We need a contract, in this way an interface in the DAL that will implement the Unit of Work:

image

First of all let’s build the C.R.U.D. implementation into a simple interface. In this case I am going to use the generics and the Linq expression because my project will work only with Linq so I do not need an high level of abstraction:

  1: using System;
  2: using System.Collections.Generic;
  3: 
  4: namespace WPF.Tutorials.VMMV.DAL {
  5:     public interface IUnitOfWork {
  6:         //Basic C.R.U.D. operations
  7:         void Add<T>(T _entity) where T : class;
  8:         void Delete<T>(T _entity) where T : class;
  9:         void Update<T>(T _entity) where T : class;
 10:         void Commit();
 11:         //Basic Select operations
 12:         IList<T> GetAll<T>() where T : class;
 13:         T GetById<T>(Func<T, bool> _condition) where T : class;
 14:     }
 15: }

Now we need the real Unit of Work that will inherit from our contract. We want also to inherit from IDisposable because otherwise we will not be able to keep alive our datacontext during the crud operations.

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: 
  6: namespace WPF.Tutorials.VMMV.DAL {
  7:     //Inherits IUnitOfWork and IDisposable
  8:     public class UnitOfWork:IUnitOfWork,IDisposable {
  9:         //A Static instance of the Linq Data Context
 10:         private static DataModelDataContext _service;
 11:         //The default constructor
 12:         public UnitOfWork() {
 13:             _service = new DataModelDataContext();
 14:         }

Now, the second step is to translate the UoW in something readable for Linq:

  1: //Add a new entity to the model
  2: public void Add<T>(T _entity) where T: class {
  3:     var table = _service.GetTable<T>();
  4:     table.InsertOnSubmit(_entity);
  5: }
  6: //Delete an existing entity from the model
  7: public void Delete<T>(T _entity) where T: class {
  8:     var table = _service.GetTable<T>();
  9:     table.DeleteOnSubmit(_entity);
 10: }
 11: //Update an existing entity
 12: public void Update<T>(T _entity) where T : class {
 13:     var table = _service.GetTable<T>();
 14:     table.Attach(_entity,true);
 15: }
 16: //Commit all the pending changes in the data context
 17: public void Commit() {
 18:     _service.SubmitChanges();
 19: }
 20: //Get the entire Entity table
 21: public IList<T> GetAll<T>()where T : class {
 22:     return _service.GetTable<T>().ToList();
 23: }
 24: //Get the first occurence that reflect the Linq Query
 25: public T GetById<T>(Func<T, bool> _condition) where T : class {
 26:     return _service.GetTable<T>().Where(_condition).FirstOrDefault();
 27: }
 28: 

Now we have a complete Unit of Work that we will use in each repository. Ops I forgot to mention that we will not have a real repository in our solution but a view model …

Tags: