Mapping Entity Keys

REF allows you to map entity keys using various identifier standards known to the ORM community. This standards will be fully explained in this section.

1. Single Key: This is the default way of mapping an identifier to an entity. A key can either be database generated (Identity, Auto Incremented ) or user generated. Single keys are much more straight forward when mapping relationships amongst entities. An example of a single key is as follows :


[Key("EmployeeID", AutoKey = true)]
public virtual int EmployeeID { get; set; }


The above snippet declares the EmployeeID property as a database generated sequence key. The Key attribute is used by the persistent framework to annotate an entity property as a key and the AutoKey=true signifies that the key value will be generated by the database.

You can simply declare a non automatic key as follows :

[Key("EmployeeID")]

2. Composite Keys: An entity can have more than one Keys, you can have as many as possible keys declared as a property within the Entity or as a Compound Key. Rapid entity allows you to define composite keys in two different ways:

(1) Multiple Keys (Vertical Mapping): This approach of composition allows you to define as many as possible properties of an entity as a key, for example, using the CustomerCustomerDemo table of the Northwind database

[Entity("CustomerCustomerDemo")]
public partial class CustomerCustomerDemo {
        
        ... other mapping

        [Key("CustomerID", AutoKey = false)]
        public virtual string CustomerID { get; set; }

        [Key("CustomerTypeID", AutoKey = false)]
        public virtual string CustomerTypeID { get; set; }
}

The code above declares two properties as a key within the CustomerCustomerDemo entity. This means that the two keys are used by rapid to identify instances of the CustomerCustomerDemo entities. And the keys are also used to fetch unique row from the CustomerCustomerDemo table.

(1) Compound Key (Horizontal Mapping): We can segregate the multiple keys (vertical mapping) into a compound mapping, by defining multiple keys into another class. This approach is more intuitive and object oriented. The key class will contain the persistent keys, and the Entity will contain the key class, using CompositeKey attribute. Lets follow this simple example while using the CustomerCustomerDemo entity :

Example: Separate the keys and put them in a compound class (CustomerDemoKey)
    public class CustomerDemoKey
    {
        [Key("CustomerID", AutoKey = false)]
        public virtual string CustomerID { get; set; }

        [Key("CustomerTypeID", AutoKey = false)]
        public virtual string CustomerTypeID { get; set; }
    }
The code above is a pure class that contains properties annotated as Keys using the framework attribute. This class (CustomerDemoKey) is a compound key which will be referenced by the owner Entity, now let us define the Entity that owns this key, and we shall see how this compound key class is related to the entity class :

    [Entity("CustomerCustomerDemo")]
    public partial class CustomerCustomerDemo
    {
         ... other mapping

        [CompositeKey]
        public virtual CustomerDemoKey MyKey { get; set; }
    }

The code above makes use of the CompositeKey attribute to signify that the MyKey property of the CustomerCustomerDemo entity is a compound key. This is an elegant way of separating keys from the actual entity class. Rapid allows you to define as many as possible compound keys for a single entity, Rapid Entity's Run time Engine can entertain as many as possible keys.

Note you cannot nest compound keys, this includes having a compound key contain another compound key.
You can use compound keys for anything you can use a single key for.

Fetching an entity with a compound key
CustomerCustomerDemo demo = manager.LoadEntity<CustomerCustomerDemo>
                                    (
                                       new CustomerDemoKey 
                                       { 
                                           CustomerID = "ALFKI", 
                                           CustomerTypeID = "TEST" 
                                       }
                                    );

You can also use an anonymous key value, so far the names of the key properties are the same
CustomerCustomerDemo demo = manager.LoadEntity<CustomerCustomerDemo>
                                    (
                                       new 
                                       { 
                                           CustomerID = "ALFKI", 
                                           CustomerTypeID = "TEST" 
                                       }
                                    );

LINQING Compound keys You can project a compound key in linq, you can also use it in conditional statments as you will do with any entity.
                var linq =( from demo in manager.AsQueryable<CustomerCustomerDemo>()
                           where demo.MyKey == new { CustomerID = "ALFKI" , CustomerTypeID = "TEST" }
                           select new
                           {
                               MyKey = demo.MyKey ,
                               CustomerID = demo.MyKey.CustomerID
                           } 
                           ).ToList();

Last edited Apr 15, 2010 at 11:29 AM by ahmedsalako, version 15

Comments

No comments yet.