Reading and writing objects

Writing objects

There are 3 methods available to store an object in the database:

  • Insert(T obj, ... relations ...)
  • Update(T obj, ... relations ...)
  • InsertOrUpdate(T obj, ... relations ...) or Save(T obj, ... relations ...)

All those methods are defined on the DataSet class and on the StorageContext class. It makes no difference which one you use.

  • Insert() will create a new record in the database.
  • Update() will update an existing record (only for records with a primary key)
  • InsertOrUpdate() will either insert a new record in the database or update the existing record. This only works for objects with a primary key
  • Save() is an alias for InsertOrUpdate()

In addition, it's possible to pass one or more relations to these methods. Any relations specified will be saved together with the record. For example:

Order order = new Order() { ... }

order.Customer = new Customer() { ... };

dbContext.Save(order, order => order.Customer);
// this will save the order record and the related customer record

Reading objects

The following methods are available to read a single object from the database:

  • Read<T>(object key , ... relations ...)
  • Read<T>(...condition..., ... relations ...)
  • Load<T>(T obj, object key, ... relations ...)

All those methods are defined on the DataSet class and on the StorageContext class. It makes no difference which one you use. If you use Read() on the StorageContext class, you need to specify the type of object to read: Read<T>(key).

Read() will read a single object with the given primary key(s) or the first object that matches the given condition. If the object isn't found, null will be returned. Load() will load data from the database for the given primary key(s) or the first object that matches the given condition and store it in the object.

Examples:

var customers = dbContext.DataSet<Customer>();

// Read a new object:
var customer = dbContext.Read<Customer>(customerId);
// or
var customer = customers.Read(customerId);
// or
var customer = dbContext.Read<Customer>(c => c.Name = "John Doe");
// or
var customer = customers.Read(c => c.Name = "John Doe");

// Read data into an existing object:
var customer = new Customer();

dbContext.Load(customer, customerId);

Optionally, one or more relation expressions can be specified. Those relations will be read together with the object:

var order = dbContext.Read<Order>(orderId, o => o.Customer);

// at this point, the Customer relation for the order will be loaded

Note that it's not required to explicitly load one-to-many relations that are defined as IDataSet. Those relations are (lazy-)loaded automatically.

Composite keys

To read an object with a composite key, an anonymous object should be passed instead of the primary key, where the properties of the object are the names of the keys, as in Read(new { Key1=value1, Key2=value2 }. The property names should match the field names of the primary keys.

Example:

ClassAssignment assignment = dbContext.Read<ClassAssignment>(new { 
                                                              ClassID = classId, 
                                                              StudentID = studentId 
                                                             });

Deleting objects

Objects can be deleted by primary key or by specifying a filter expression:

var products = dbContext.DataSet<Product>();

products.Delete(productId);

// or

products.Delete(p => p.ExpirationDate < DateTime.Today);

Using ActiveRecord extensions

To make it easier to work with the methods discussed above, you can use extension methods to read, save and delete objects:

Customer customer = new Customer() { ... };

customer.Save(); // is equivalent to dbContext.Save(customer)

customer.Delete(); // is equivalent to dbContext.Delete(customer)

To be able to use those extension methods, your object classes should implement the IEntity interface. The interface doesn't have any methods as it is just a marker to tell Iridium that it should add extension methods to your classes.

These methods only work when you have just one active StorageContext. When the first StorageContext instance is created in your application, the static property StorageContext.Instance will be set to that instance.