2009-12-28

WPF applications and DataObjects.Net

During last two weeks I've been working on new WPF sample for DataObjects.Net. In contrast to existing WPF-sample it will embrace wide variety of scenarios usually used in WPF or WinForms applications. The first version of the sample will be built as 2-tier application using DisconnectedState approach. It will be mainly focused on following aspects:

 - Working with Sessions and DisconnectedStates
 - Managing WPF events
 - Data binding

By this moment I am communicating with several community members who use DataObjects.Net in WPF applications. There are a lot of questions and support requests related to these aspects.

By the way, I'd like to provide two versions of this application: Plain WPF and MVVM (Model-View-ViewModel pattern) version. Surely MVVM  is the most attractive pattern to use in WPF application. On other hand, it's rather difficult to find good real-life MVVM implementation example.

My optimistic plan implies that some ready for use sample will be published till the New Year.

2009-12-09

"Soft Delete" (aka "Logical Delete") in ORM

People often ask which ORM supports "Soft Delete" or "Logical Delete". Let's try to figure out what is it and whether ORM should internally support it.

"Soft Delete" is a way of removing business entities, which implies that we mark an entity as deleted instead of physical removing it from database. This approach is often used in Line of Business applications because of its several advantages:
  • It allows us to keep history for different  auditing sceneries. For example, somebody removed one document in the past from our workflow system, we surely want to be able to audit removing log and data removed document contained.
  • It allows to implement Recycle Bin approach in easy way. We'd like to be able to recycle any document removed in the past.
To implement "Soft Delete" feature in a simple case we should:
  • Create IsDeleted persistent property of bool type in all softly removable types.
  • Automatically filter all queries, i.e. automatically add Where(entity => !entity.IsDeleted) to each LINQ query.
In my example on DataObjects.Net I use single base class for all business objects, so I can add IsDeleted field to this class:

public class BusinessObject : Entity
{
  [Field]
  public bool IsDeleted { get; set;}

  public new void Remove()
  {
    IsDeleted = true;
  }
}
Then let's create DataContext class responsible for data access:

public static class DataContext
{
  public static IQueryable<T> GetAll<T>()
    where T : BusinessObject
  {
    return Query<T>.All
      .Where(entity => !entity.IsDeleted);
  }
}

Now we can softly remove our entities and query not removed ones. I've created small sample illustrating model of blog-publishing service, consisting of three classes: Blog, BlogPost and Comment. So I can query recent posts from my blog using such LINQ-query:

from post in DataContext.GetAll<BlogPost>()
where
  post.PublishDate > DateTime.Now-TimeSpan.FromDays(7) &&
  post.Blog == myBlog
select post;

This query will return all posts except softly deleted and I don't have to add appropriate check to every query in my application.

Generally, I am sure that "Soft Delete" shouldn't be internally implemented within an ORM framework, because it's easy to implement it yourself and your own implementation will be more flexible than built-in. Why flexibility is important? In my example I've chosen the simplest way of its implementation. In real-life scenarios there are many aspects connected with soft deletion in specific ways, for example:
  • Security: You may want to define who has a permission to access removed entities, etc...
  • Entities dependency: You may want to consider some entities as deleted when their dependency parent is deleted, so you need to specify more complex filter on queries.