Quick Start

You can download the full source of this article here.

Introduction

In this article you will learn how to create a simple Console application for persisting your own business classes into a simple XML repository. Then we will switch the repository to a dedicated relational database without changing any line of code.

Creating the business layer

For the sample we use a simple Customer and Order model. The classes are added to a class library project called QuickStart.Domain.
Here is a schema representing those classes.
diagram.png
The classes as are simple as that.

namespace QuickStart.Domain
{
    public class Customer
    {
        protected string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        protected IList<Order> orders = new List<Order>();

        public IList<Order> Orders
        {
            get { return orders; }
            set { orders = value; }
        }
    }

    public class Order
    {
        protected int amount;

        public int Amount
        {
            get { return amount; }
            set { amount = value; }
        }
    }
}
Remark: Members are declared protected as it is a recommendation for Euss and for object design in order not to have Euss access public properties. Though you can declare them private if you need. Collections are declared as IList as required by Euss.

Configuring the repository

Create a Console application named QuickStart.Console and add an app.config configuration file to it.
Copy-paste the code below to this file.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 
  <configSections>
    <section name="evaluant.uss" 
             type="Evaluant.Uss.Configuration.EussConfiguration, Evaluant.Uss"/>
  </configSections>
 
  <evaluant.uss>
    <engines defaultEngine="QuickStartXml">
      <engine name="QuickStartXml" factory="Evaluant.Uss.Xml.XmlProvider">
        <add name="FileName" value="~/quickstart.xml"/>
        <metadata>
          <add type="assembly" value="QuickStart.Domain"/>
        </metadata>
      </engine>
    </engines>
  </evaluant.uss>
 
</configuration>

This file simply tells Euss to use the XmlProvider class as the repository engine to use, and the properties it needs to behave correctly, that is to say the FileName only. Whatever the persistence engine chosen is, the configuration also needs some information about what to persists (the medata), and this is configured to be found inside the assembly named QuickStart.Domain.

Finally we add a reference to the assembly named Evaluant.Uss.dll" and to the project QuickStart.Domain*.

Coding the application

First we create an ObjectService which will contain all the information about the persistence engine to use. This instance can be shared inside an application and is thread safe. For instance in an ASP.NET application, this could be declared static and would be load the configuration only once.

ObjectService os = new ObjectService();

Then we instanciate an ObjectContext using the previous ObjectService instance as a factory for it. This class stands for a connection to the repository, but the object way.

ObjectContext oc = os.CreateObjectContext();

For the needs of this demonstration we then delete any previously existing data in our repository by initializing it.

oc.InitializeRepository();

Here we can create our business entities to persist.

Customer c = new Customer();
c.Name = "Eric";
 
Order o1 = new Order();
o1.Amount = 10;
 
Order o2 = new Order();
o2.Amount = 20;
 
c.Orders.Add(o1);
c.Orders.Add(o2);

To persists this entites we just call Serialize() in the scope of a transaction.

oc.BeginTransaction();
oc.Serialize(c);
oc.CommitTransaction();

And finally we request some data from the repository, and display the result

IList<Order> myOrders =
  oc.Load<Order>(typeof(Customer), "[Name = 'Eric'].Orders");
 
foreach (Order o in myOrders)
  Console.WriteLine(o.Amount);

Here is the complete source.

using System;
using System.Collections.Generic;
using System.Text;
using QuickStart.Domain;
using Evaluant.Uss.ObjectContext;
 
namespace QuickStart.Application
{
    class Program
    {
        static void Main(string[] args)
        {
            ObjectService os = new ObjectService();
            ObjectContext oc = os.CreateObjectContext();
            oc.InitializeRepository();
 
            Customer c = new Customer();
            c.Name = "Eric";
 
            Order o1 = new Order();
            o1.Amount = 10;
 
            Order o2 = new Order();
            o2.Amount = 20;
 
            c.Orders.Add(o1);
            c.Orders.Add(o2);
 
            oc.BeginTransaction();
            oc.Serialize(c);
            oc.CommitTransaction();
 
            IList<Order> myOrders = 
                oc.Load<Order>(typeof(Customer), "[Name = 'Eric'].Orders");

            foreach (Order o in myOrders)
                Console.WriteLine(o.Amount);
        }
    }
}

Using a relational database

In order to change the persistence mecanism the only thing to do is to change the repository configuration. For this to be done we add an engine tag like this:

      <engine name="QuickStartSql" factory="Evaluant.Uss.SqlMapper.SqlMapperProvider" 
              connectionStringName="QuickStart">
        <add name="Dialect" value="Evaluant.Uss.SqlMapper.MsSqlDialect"/>
        <add name="Driver" value="Evaluant.Uss.SqlMapper.MsSqlDriver"/>
        <add name="MappingFileName" value="~/QuickStart.Domain.eum.xml"/>
        <metadata>
          <add type="assembly" value="QuickStart.Domain"/>
        </metadata>
      </engine>

The connection string can be defined in the standard section like this:

  <connectionStrings>
    <add name="QuickStart" connectionString="Server=localhost;Database=quickstart;UID=sa;PWD="/>
  </connectionStrings>

Remark: The default engine has been changed to QuickStartSql. You should also change the connection string and check that the database is existing.

The SqlMapperProvider class needs three important arguments:
  • The dialect which handles the generated SQL strategy, specific to each database vendor
  • The driver (oledb, native, ...)
  • The mapping file, defining the tables and fields which will be used to store the business entities

Even if you can define it as you like, the mapping file can be automatically generated from your business entites directly. This is a recommended solution for new projects. For existing databases this file must be created specifically. The tool to generate this file is mapping.exe. Please read the documentation for more information on its usage.

In our case the commande line to generate the mapping would be:

mapping.exe /assembly:"QuickStart.Domain.dll" /out:"QuickStart.Domain.eum.xml"

And the generated file is:

<?xml version="1.0" encoding="utf-8"?>
<Mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Entity type="QuickStart:Domain:Customer" table="Customer">
    <Id field="CustomerId">
      <Generator name="guid" />
    </Id>
    <Attribute name="Name" field="Name" db-type="String" size="50" />
    <Reference name="Orders" entityChild="QuickStart:Domain:Order">
      <Rule parentField="CustomerId" childTable="Order" 
            childField="FK_CustomerId" />
    </Reference>
  </Entity>
  <Entity type="QuickStart:Domain:Order" table="Order">
    <Id field="OrderId">
      <Generator name="guid" />
    </Id>
    <Attribute name="Amount" field="Amount" db-type="Int32" />
  </Entity>
</Mapping>

We add it to the project, and change its property to Copy to Output Directory.

That's all !

Last edited Aug 8, 2008 at 8:55 AM by sebastienros, version 7

Comments

No comments yet.