ELENESSKI GAMES
  • Home
  • Games
    • Worzzler
    • The Lost Tribes
  • Unity
    • Facade Generator for Archimatix
    • Elenesski Object Database
    • Generic Move Camera
    • Unity C# Library
  • SQLINQ
    • Change Log
    • Concepts >
      • Overview
      • The Patterns
      • Database & Factories
      • Working with Tables
      • Custom Queries
      • Lazy Loading
      • Units of Work
    • Video Tutorials
    • Getting Started
    • Code Examples >
      • Implementing Behavior
      • Finding Objects
      • Custom Searches
      • Converters and Transformers
      • Object Association Management
      • New Objects
      • Creating Database
      • Associating Objects
      • Deleting Objects
      • Validating Objects
      • Saving
    • Sample Model >
      • Tutorial Model
      • Table Classes Code
      • Domain Classes Code
      • Factories Code
    • OSX Developers
    • Bridge Building
    • External Websites
    • Class Documentation
  • Presentations
    • 3D Ship Design
  • Music
    • Jamendo (Main)
    • Blend
    • Sound Cloud
    • Mixcloud (DJ)
    • DJ Demos
  • YouTube

Understanding and using units of work

A unit of work refers to a collection of changes that need to be saved in the database as a set.  If not all the instances can be saved, then the entire set of changes are rolled back.  By default, SQL LINQ implements a Identity Map.  This keeps in memory a record of all instances that have been loaded from the database, so that if that same instance is loaded again, the in memory instance is used, not a copy of the database version (which might not have been committed yet.)

To use a unit of work, you need to be setting the isDirty flag on all your domain class attributes.  The order the dirty flag is set dictates the order changes are applied to the database.  For example, if deleting a master with several children, you delete the children first, then the master, to prevent orphan children from being created or the master delete failing due to a referential integrity check.

To do this, you need change how your domain class properties work.  For example, consider the Town class constructor from above.  When the constructor is called, it passes all of the attributes into properties.  Let's look at how Name is assigned in the constructor (ignoring the other attributes):

        public Town(int aOID, string aName, float aLatitude , float aLongitude, int aThePlanetOID) : base(aOID) {
           
Name= aName;
        }

Which might look like this for the attribute Name:

      public string Name { get; set; }

This approach won't work if you need to use a Unit of Work.  Why?  Because you need to be able to set isDirty when the value changes.  Therefore you need an internal variable and a property that works like this:

      private string _Name;
      public string Name {
          get {
                return _Name;
          }
          set {
                if ( value != _Name ) {
                     isDirty = true;
                     _Name = value;
                }
          }
      }

And the constructor needs to change too ... to set the internal variable.  Because if it sets the property, every loaded object becomes dirty:

        public Town(int aOID, string aName, float aLatitude , float aLongitude, int aThePlanetOID) : base(aOID) {
           
_Name= aName;
        }

In your BaseClass.Validate() method, if you want to fail the Save for any reason, you set the message and return an error from the Save.

         public override
ValidationResult Validate() {
              
ValidationResult myResult = new ValidationResult();
               myResult.Add( MessageType.Error , "This failed." );
               return false;
         }


Now once you have reorganized your domain objects, performing a Unit Of Work commit is very easy:

       
ValidateResult SUCCESS = Repository.Commit();