Randolph Cabral’s Weblog

…beauty is just a dimmer switch away…

Archive for the ‘Jammer.NET’ Category

Exploring N-Tier Architecture with LINQ to SQL (Part 1 of n)

Posted by Randolph Cabral on Wednesday, April 23, 2008

Part 1 – Analyzing LINQ to SQL Entities

For the past six months or so I’ve been playing a lot with LINQ to SQL to dissect and examine the internals of what makes it tick.  It didn’t take long before I became a fan of LINQ to SQL, expression trees and IQueryable<T>.  Those guys at Microsoft have really hit the nail on the head with this stuff.  I started writing lots of LINQ to SQL code, debugging and watching SQL Profiler.  I had a blast trying to find ways to break it.  For the most part, it did really well in producing accurate, not always concise, SQL statements; albeit some queries could stand to be refactored.  Regardless, LINQ to SQL delivers beyond my expectations.  This is the point where I started to look for an elegant way to integrate LINQ to SQL with a classic N-Tier architecture.  Unknowingly, I took the “red pill” and I dove head first into the rabbit hole.  “How hard can this be?”, I thought to myself.

In my previous post, I compared the relative merits and challenges of the Active Record pattern with the Unit of Work pattern.  The Active Record pattern, in my opinion, creates a natural coding paradigm where business objects expose persistence behaviors as public methods.  The challenge being that Active Record implementations ranging from Ruby to Subsonic to Jammer.NET have had issues with cardinality.  Since most Active Record implementations do not implement the Identity Map pattern, lazy loading relationships in the object graph could create an infinite loop condition when recursive persistence logic is invoked.  LINQ to SQL avoids these types of issues by implementing the Unit of Work pattern through its DataContext class.  Because the DataContext tracks object state, persistence calls are batched with only those objects that need to be updated and there would be no need to traverse the object graph.  A challenge with the DataContext lies with cases where the objects become disconnected from the DataContext.  Another potential issue with the DataContext, in my opinion, is code clutter.  I personally don’t like having logic to re-attach disconnected objects to the context cluttering up my code.

Weighing both patterns and considering their benefits and disadvantages, I decided to try an experiment to marry the two patterns.  The Active Record persistence behaviors can encapsulate the logic required for re-attaching and, in turn, the Unit of Work container can handle tracking of object state and persistence.  The only thing missing is the minister and a prenup to make it official.  So off I go to try my hand at match-making.

Let’s inspect the entity class that was generated by LINQ to SQL’s code generator (SQLMetal).  Firstly, as seen in the following code sample, each generated class is adorned with a TableAttribute to create a mapping to the database table.  Additionally, the class is declared partial to allow for customizations to be kept in a separate file.  This is nice, but falls short for our desire to create a business layer on top of these data entities.  The class then implements a couple of interfaces from the System.ComponentModel namespace to support notification of property changes.  It is really nice that it doesn’t need to derive from a concrete class as this gives us the opportunity to create a custom base class that all entities can derive from should we choose to do so.  Unfortunately, the class is not adorned with the SerializableAttribute.  The designer allows you to control the “Serialization Mode”, but this does not do what I was expecting it to do.  Setting this property to “Unidirectional” causes the properties of the data entities to get adorned with a DataMemberAttribute which is a WCF XML serialization method.

//LINQ to SQL’s mapping attribute implementation

[Table(Name=“dbo.Customers”)]

public partial class Customer : INotifyPropertyChanging, INotifyPropertyChanged

{

  …

}

Looking further in the class I found the public property mapping implementation.  I was surprised to find its mapping attributes were adorned to the public properties (below).   I was surprised because this meant that I could hide the mapping by simply deriving from the class and declaring a new property with the same name.  What about polymorphism? I know what you’re thinking, this is supposed to be a data entity not a domain entity.  I agree.  However, I’m a believer in code reuse.  If the data model entities closely match the domain model, why not derive from those entities to maximize code reuse?  Furthermore, your domain entities can completely encapsulate domain logic from the data entity without having to model yet another class that implements all of the same properties.  In other words, you get all of the data without all of the work for free.  All that’s left to do is to write the business logic in a class that elegantly holds only business layer implementation.  So naturally, I was surprised to see the mapping made at the property.

//LINQ to SQL’s mapping attribute implementation

[Column(Storage = “_CompanyName”, DbType = “NVarChar(40) NOT NULL”, CanBeNull = false)]

public string CompanyName

{

  get { … }

}

I later realized that LINQ to SQL deliberately creates mappings this way in order to support deferred execution.  Because the public property is the referenced member of the class in the expression tree, a simple reflection call is all that is needed to retrieve the attribute instance.  Formatting a SQL command statement becomes possible this way and is, indeed, a very nifty way of storing schema details without the need for an external mapping file (as found with the Hibernate mapping paradigm).  I prefer having an inline attribute-based approach to Hibernate’s XML-based mapping files.  I’ve always felt that having the mapping definitions inline with code was a cleaner way to implement mappings as the definitions are always only a click or two away.  However, I do recognize the simplicity and elegance of an external mapping file as well as having the ability to cache the map in memory for performance.

As a quick test, I tried to derive from the LINQ to SQL entity and run a query from the context with out success.  The reflection call that discovers the mapping attribute does not flatten the hierarchy and can’t retrieve the base property reference.  Bummer.  Microsoft, if you’re reading this, please modify the GetProperty() method call to include a binding flag value of “BindingFlags.FlattenHierarchy”.  I think it would be really cool to have business objects that derive from data objects that are context connected.  Maybe the answer is to wait for the ADO.NET Entity Framework for this type of support.

Next, we find the associations section.  This is where relationships to other entities are made.  Here we are introduced to the AssociationAttribute and the EntitySet<T> object.  The EntitySet<T> came as a surprise to me because I was expecting a simple Collection<T> or even simpler, an array of Order objects to handle relationships.  According to the MSDN documentation for EntitySet<T>, it provides deferred loading and relationship maintenance for the one-to-one and one-to-many collection relationships for LINQ to SQL applications.

[Association(Name=“Customer_Order”, Storage=“_Orders”, OtherKey=“CustomerID”)]

public EntitySet<Order> Orders

{

  get

  {

    return this._Orders;

  }

  set

  {

    this._Orders.Assign(value);

  }

}

Another relationship object that is found in the generated code is the EntityRef<T> class.  Again, for deferred loading purposes a specialized class is used to handle direct parent relationships.

private EntityRef<Customer> _Customer;

How do these references get instantiated? Well, with the constructor of course! Yeah, I was confused at first too.  The concept to note here is that the EntitySet<T> object is instantiated but not the actual entity until the Entity property is requested.  I’m not sure what to think of this one.  I’m guessing they wanted to push the responsibility of tracking when a related entity has been requested to another class in an effort to keep things clean with the entity class implementation.  Certainly, this could have been achieved by adding more properties to the class.

public Customer()

{

  this._Orders = new EntitySet<Order>(new Action<Order>(this.attach_Orders), new Action<Order>(this.detach_Orders));

  …

}

So far so good.  The entities generated by LINQ to SQL are relatively straight forward and relationships to other entities are handled relatively elegantly.  The class does not derive from another concrete class and there is no data access logic to muddy up the waters.  Inline attributes and the use of custom relationship classes make up the list of less desirable items, but shouldn’t impede our efforts to create an N-Tier architecture.  Out of the box, LINQ to SQL provides an excellent way to quickly model a data layer with rich relationship structures.

In the next post, we’ll take a look at the DataContext class and evaluate how we could best take advantage of its object tracking capabilities.  I’ll also explore writing a context manager class that helps ease the pains in dealing with the DataContext.

Posted in Active Record, C#, Domain Model, Jammer.NET, LINQ to SQL, Object Oriented Programming, POCO, Software Architecture | Tagged: , , , , , | 2 Comments »

Active Record Vs. Unit of Work

Posted by Randolph Cabral on Thursday, April 3, 2008

Lately, I’ve been doing some research on which path to take – Active Record or a pure Domain Model using the Unit of Work pattern.  Clearly there are advantages and disadvantages to both.  I’m hoping to find a good compromise between simplicity and flexibility.  When I say ‘simplicity’, I’m talking about the ever-elusive ‘elegant solution’ where we are free from framework traps and anemic domain models.  As for ‘flexibility’, I’m referring to the ability to quickly change delivered functionality without having to rip apart the guts of the existing code base.  The thing that I keep getting hung up on is deciding which of the two best fits these goals.  I’ve used both approaches and like them both, but this is one of those debates that has no clear winner.  Let’s take a closer look at each approach.

The Active Record Pattern

In this model, an entity and its properties are directly mapped to a database table and its columns.  Additionally, every entity is implemented with its own insert, update, delete and select (CRUD) behaviors.  Method names like Save, Delete and Load are commonplace with many Active Record implementations.  Rounding out the package adds various static methods that expose query capabilities to allow filtering.  Having these behaviors included with the entities provides a convenient way of persisting state back to a data source.  I have used this pattern a lot and have had many successful projects that I credit the pattern for.  Needless to say, as with most solutions, it isn’t perfect.  There are a few cases where this pattern can create some interesting challenges.

Consider this case:  Cardinality, A.K.A. relationships with other entities.   Think of the classic customer and order example.  A customer can have many orders which is to say that the customer object has a one-to-many relationship with order objects.  Remember, the Active Record pattern exposes public Save methods on both the customer object and the order object.  What would you expect to happen when you call the Save method on the customer object?  Certainly the customer object will be saved to the database, but what about the orders?  If you’re using Ruby’s Active Record implementation, the orders that are associated with the customer object may or may not be saved depending on whether the customer’s Save method call is an initial or subsequent call.  Using Jammer.NET’s implementation, the associated orders are not saved at all.  The developer must take action by either modifying the Save method on the customer object to handle cascade saving or by calling the Save method on the orders collection manually.

The Unit of Work Pattern

According to Martin Fowler’s anemic domain model anti-pattern, the domain model should only have objects that are named after the nouns in the domain space and connected to each other with rich relationship structures.  Furthermore, the behaviors of each object should model only those rules that are domain space specific.  This means that the Active Record pattern violates this rule because CRUD behaviors are forms of data store persistence logic not domain space logic.  Going by this definition, we must implement persistence using the Unit of Work pattern.  Two great examples of this pattern is implemented by Hibernate and Microsoft’s LINQ to SQL technology.  Hibernate and LINQ to SQL take a sort of hybrid approach which combines both the Active Record pattern’s metadata mapping and the Unit of Work pattern.  This hybrid approach creates a very clean model for handling persistence regardless of cardinality between entity objects.  Using LINQ to SQL, the entities, for the most part, adhere to the notion of POCOs which are persistence ignorant.  Great right? Unfortunately, as with the Active Record approach, this model is also not without its challenges.

Consider this case: Objects that become disconnected from its Unit of Work container.  Let’s assume that you are writing a web application and you’re coding up a three step registration wizard.  Ideally, having the UoW container stay in scope through completion of the wizard is preferred.  Unfortunately, that may not be the best idea if your application needs have as light a footprint on memory usage as possible.  Considering this, you decide to let the UoW container go out of scope once your business objects are loaded causing the business objects to become disconnected.  Finally, the registration wizard reaches its last step which is to persist the state of the registration business object to the data store.  Because the UoW container got garbage collected a new container instance must be created and the business object must be re-attached.  I know what you’re probably thinking, “This logic is not so hard to write.  Why all the heartburn?”  The problem I have is with the additional lines of code that must be written to re-attach the entities.  These lines of code are entirely house keeping items that, in my opinion, muddy up the code.  In my opinion, this pattern also does not code as naturally as the Active Record pattern.  However, I do think it’s the better pattern in the sense that related entities are automatically handled by the UoW container.

Sound Off!

So what do you think?  Which pattern gets your vote?  Have I missed anything?  Help me to choose which way to go.  I’m sure this debate will likely live on for many years and I look forward to hearing from all of you.

Posted in Active Record, C#, Domain Model, Jammer.NET, LINQ to SQL, Object Oriented Programming, POCO, Software Architecture | Tagged: , , , , , , , , , | 2 Comments »