Advanced Features

Object Data Blocks supports inheritance through the specialisation of existing persisted classes. The following two classes inherit all the properties of the Person class. Abstract classes are combined into a single table whilst non-abstract classes are joined together transparently.

public class Customer: Person
{
   [Column, SqlFixed(9,2)]
   public decimal CreditLimit() {get; set;}
}

public class Employee: Person
{
   [Column]
   public string JobDescription {get; set;}
}

Common database features such as key identity creation, indexes and referential integrity can be added through the use of attributes. In this example we create a primary key with an auto-generated value and we specify the maximum length of the string data in the Line1 column. The Address type is used for the ShippingAddress so that these fields are always available when retrieving an order. Enumerations are also permitted as a column type.

public enum AddressType
{
   Shipping = 0,
   Billing = 1
}

public class Address: Table
{
   [PrimaryKey, SqlIdentity(1,1)]
   public int Id {get; set;}

   [Column, SqlLength(255)]
   public string Line1 {get; set;}

   [Column]
   public AddressType Type {get;set;}
}

public class Order
{
   [PrimaryKey, SqlIdentity(1,1)]
   public int Id {get; set;}

   [Column]
   public Address ShippingAddress {get; set;}

   [UniqueIndex]
   public string Reference {get; set;}
}

Tables level attributes can also be added to specify compound keys and indexes , and other table-level information. In the next example, an association is created between customers and address's and a primary key is specified that is a combination of a valid Customer Id and Address Id.

[PrimaryKeys("CustomerId","AddressId")]
public class CustomerAddress
{
   [ForeignKey(typeof(Customer)]
   public int CustomerId {get; set;}

   [ForeignKey(typeof(Address)]
   public int AddressId {get; set;}
}

Multiple updates can be grouped together atomically using built in support for .net Transaction Scopes. The following example creates a new address record and associates the record with an existing customer.

using (TransactionScope scope = new TransactionScope())
{
   var address = new Address();
   address.AddressType = AddressType.Shipping;
   address.Insert(command); //the identity value is placed into the address object

   var customerAddress = new CustomerAddress();
   customerAddress.CustomerId = 1;
   customerAddress.AddressId = address.Id; 
   customerAddress.Insert(command);

   //Complete transaction
   scope.Complete();
}   


All customers and their address's can be retrieved using the Query<T> class. The following example prints address labels for each customer. Each customer must start on a new page.

var customerQuery = new Query<Customer>();
var customerAddressQuery = new Query<CustomerAddress>();
var addressQuery = new Query<Address>();

customerQuery.Join(customerAddressQuery, "Id", "CustomerId");
customerAddressQuery.Join(addressQuery,"AddressId", "Id");

using (QueryDataAdapter adapter = customerQuery.Execute(command))
{
   while (adapter.Read())
   {
      if (customerQuery.Binder.HasChanged) 
      {
         Customer customer = customerQuery.Item;
         PrintNewCustomer(customer)
      }
      PrintAddressLabel(addressQuery.Item);
   }
}

Last edited Jan 19, 2010 at 7:24 PM by JamesWestgate, version 22

Comments

No comments yet.