The Mapping Application Block QuickStart Sample Application
The sample that is supplied with the Mapping Application Block is contrived to demonstrate all of the key features of the Mapping Application Block. The data used in the sample application comes from a local SQL Server Database so the application elicits the help of the QAB to manage the queries and thus demonstrates the seamless partnership of these two application blocks in managing your data access layer (and lets not forget that as we are using data from a SQL database then the good old DAAB is there too).
Note: before trying out the samples please check the configuration files with the
Enterprise Library Configuration Console. The samples use the
MappingQuickStart.mdf database as an attached file with absolute path names. These files are quite likely to be in a different place on your computer as they were on mine. You may also need to check that these files are not set as
read-only as both the application and the database were developed in a source controlled environment requiring the database files to be checked-out before testing to remove the read-only flag.
The following shows the main WPF form for the
Domain Object Viewer divided into a list of
Basic1 items on the left and a tabbed control showing, in respective tabs, Basic1 object properties and lifecycle audit information on the right:

The viewer starts with a pre-populated list of Basic1 items in a list. As you select an item from the list then its properties are displayed in the panel to the right. If you select the
Audit tab then you will see audit information showing when the object was created, last updated and possibly even marked as deleted. The status bar at the bottom shows you how many Basic1 items are in the list and whether the collection of Basic1 items has been changed or not. From the Properties tab you can change some of the properties, these changes are not committed to the database straight away but held in memory until the
Save toolbar button or menu option is pressed. If you press the
Refresh button, or menu option, then the
Basic1 collection will be re-read from the database and any uncommitted changes cancelled. You will notice that when changes have been made the word
Changed appears in the bottom right of the status bar and reverts back to
Unchanged after the changes have been saved. If you try to close the application with changes outstanding you will get a warning, no matter how you close the application, even if you try to shutdown your computer.
The key components, from the perspective of demonstrating the MAB, are the
DomainObjectController and the domain objects themselves. The
DomainObjectController handles the reading and writing of
Basic1 objects.
The
GetBasic1Collection() static method gets the collection of Basic1 objects from the database, this collection is then cached until a
Save or
Refresh action is performed:
[C#]
/// <summary>
/// Read the full collection of *Basic1* domain objects from data storage.
/// </summary>
/// <returns>a collection of Basic1 objects, including ones marked as deleted</returns>
public static ICollection<Basic1> GetBasic1Collection()
{
ICollection<Basic1> basic1Collection =
MapperFactory.CreateMapper("Basic1 Mapper").ToDomainObjectCollection<Basic1>(QueryFactory.CreateQuery("Read Basic1 All").ExecuteForRead());
CancelChangesInBasic1Collection(basic1Collection);
return basic1Collection;
}
When you press the
Save button, or menu option, the
SaveChangesInBasic1Collection() method is called that uses the MAB in the opposite direction to save a collection of
Basic1 objects back to the database:
[C#]
/// <summary>
/// Saves the changes in basic1 collection.
/// </summary>
/// <param name="basic1Collection">The basic1 collection.</param>
public static void SaveChangesInBasic1Collection(ICollection<Basic1> basic1Collection)
{
Collection<Basic1> dirtyBasic1Collection = new Collection<Basic1>();
foreach (Basic1 basic1 in basic1Collection)
{
if (basic1.IsDirty)
{
basic1.IdentityId = identityId;
dirtyBasic1Collection.Add(basic1);
basic1.IsDirty = false;
}
}
QueryFactory.CreateQuery("Update Basic1").ExecuteForWrite(MapperFactory.CreateMapper("Basic1 Mapper").FromDomainObjectCollection(dirtyBasic1Collection));
}
Note how an
IsDirty property is used to determine which objects have changed to reduce the amount of work sent to the database by only sending those objects that have changed.
There is another place where the MAB is used, and that is in some of the domain objects themselves using a technique known as
Lazy Load. The
Audit data is an example, because the Audit information is separated off to its own Tab it may or may not be viewed.
Lazy Load is employed, using the MAB inside the properties of a domain object, to ensure that this information is only read from the database when first requested, thereafter it is cached for subsequent display so you get at most one read but in many cases there is no need to read the data at all:
[C#]
/// <summary>
/// Audit data property, only read on request.
/// </summary>
/// <remarks>Lazy load is employed to reduce the overhead of data reads</remarks>
public Audit Audit
{
get
{
if (audit == null)
{
if (id != Guid.Empty)
{
IDictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("PrimaryId", id);
parameters.Add("SecondaryId", id);
audit = MapperFactory.CreateMapper("Audit Mapper").ToDomainObject<Audit>(QueryFactory.CreateQuery("Read Audit By Id").ExecuteForRead(parameters));
}
}
return audit;
}
}
Here is the data displayed when the Audit tab is pressed:

The
Basic1 object itself employs a
Basic Mapper to handle its data in and out of data storage, however one of its properties is an Owner object that employs a
Super Mapper because there are 3 super types of Owner: a
PersonOwner, a
MachineOwner and an
OrganisationOwner. To be able to display the name of the
Owner on the
Properties tab the MAB has been deployed, using Lazy Load techniques again, to create an instance of an
Owner object of the appropriate super type and then use its
Name property to display on the tab panel. From inspection of the Domain Object classes you will see the name itself comes from a further instance of a linked
Person,
Machine or
Organisation determined by the super type class.