As most of you may already know, Telerik OpenAccessORM uses the TrackedList<T> to manage the collection fields of its persistent classes. The objects that belong to such collection are in a 1-n relation with the parent object that ‘owns’ the collection.


Before getting to the point of this post, let me put few words about the behavior of the TrackedList<T>. When a new object is added to a TrackedList<T>(ex: order.OrderDetails.Add(someDetail) ),Telerik OpenAccess ORM persists that object to the database. The new object has a reference to the owner of the collection to which it was added. 


When one removes an object from such collection, the object stays persisted in the database but has no reference to any parent object. The reference is being removed from the join table or foreign key column in the database. That leaves room for adding that object again to the collection of a different object at scenarios where the business logic allows that.


This post was inspired after a discussion we recently had with a customer. He liked using the collections to manage his object graph in terms of adding, but removal was leaving invalid records in his database.
He was asking if there was a setting to make order.OrderDetails.Clear() remove the records  from the database. Not only their references. Otherwise he would have ‘order details’ that do not belong to any ‘order’ and had to explicitly delete them in additional calls.
We told him there is no setting that would change the behavior of the TrakedList<T>, but there is still a way to make your life easier.
Just derive from it and add some of your own logic so it can fit your requirements.
Here is a sample implementation we did for his case. Remove() and Clear() were the only methods in question:

    public class CustomList<T> : TrackedList<T>
   
{
       
public override bool Remove(T item)
       
{
           
IObjectContext context = Database.GetContext(item);
           
try
           
{
               
if (context != null)
               
{
                   
if (!context.Transaction.IsActive)
                       
context.Transaction.Begin();
                   
base.Remove(item);
                   
context.Remove(item);
                   
return true;
               
}
               
return false;
           
}
           
catch
           
{
               
if (context.Transaction.IsActive)
                   
context.Transaction.Rollback();
               
return false;
           
}
       
}
       
public override void Clear()
       
{
           
if (this.Count > 0)
           
{
               
IObjectContext context = Database.GetContext(((PersistenceCapable)this[0]));
               
try
               
{
                   
if (context != null)
                   
{
                       
if (!context.Transaction.IsActive)
                           
context.Transaction.Begin();
                       
base.Clear();
                       
context.Remove(this);
                   
}
               
}
               
catch
               
{
                   
if (context.Transaction.IsActive)
                       
context.Transaction.Rollback();
               
}
           
}
       
}
   
}

That way everyone can control how Telerik OpenAccess ORM handles his/her one-to-many relations. The behavior can be almost completely changed to the one described at the beginning. Imagine implementing your own cascading delete logic etc..  A sample application demonstrating the above said is available here.

Comments

Comments are disabled in preview mode.