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 Domain Object Viewer

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 Domain Object Viewer Audit Tab

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.

Last edited Jun 20, 2010 at 9:26 AM by ewdev, version 11

Comments

No comments yet.