Mar 052014
 

Introduction

Hello and apologies for the long delay between articles, I am now returning to the Entity framework.  Following on from the previous article (Entity Validation) I’m back to review the latest edition of the generic data access class.

In the time between my original series of articles concerning disconnected POCO entities and a generic approach in handling them, I’ve refactored the class(es) a fair bit, to make the code a little more pleasant.  If you want to jump straight to the sample solution, I’ll place a link to it here and at the end of the article.

This article was originally published at Sanders Technology.  Check the site for updates and additional technology goodness.

This is a direct update to this former article: Flexible Data Operations.

Re-introducing the Data Access Base Class™

The concept was clear – have a base class which could be extended (by virtue of derived classes) which implements a common interface and provides very obvious functionality, such as Select, Insert, Update and Delete.

Being generic, the generic data access class is designed to work on a per-class basis, but when object graphs are introduced into the mix (courtesy of relationships or navigation properties), we end up having to deal with multiple classes.

Now, to quote an earlier article, here are the design prerogatives yet again:

Generic Implementation Design

I’m not going to go through the class function by function (too time consuming) however I do want to walk through the design decisions I made when considering this approach.

  1. Reusable

    The original intention was to conserve and protect the usage of the EF’s DbContext.  However, I also wanted an ability to encapsulate common queries in classes deriving from the generic implementation.  In the end I came up with the solution presented here.  Chances are high that there’s a more elegant approach, and I’m happy to hear from folks with suggestions.

  2. Generic

    Another key was to try and encapsulate as much of the common ‘CRUD’ functionality as possible without having to do things that were entity or type-specific.  Generally, with the exception of schema details and relationships, the approach to data access should be as uniform as possible, and so it should be with the mechanisms controlling such access.

  3. Flexible

    As always, providing a useful and flexible interface is a design goal.  There’s not much point introducing a repository or interface based design if consumers will write hacky workarounds to do something they need to do.  Hence, the exposure of IQueryable<T> return types.

  4. Extendable

    Chances are you’ll never fully anticipate all needs, and this is certainly true with persistence.  The aim here is that the generic approach can be extended fairly easily to prove realistically any capability that might be required down the track.  For example, a type-specific accessor (repository) could be implemented on top of the generic class to provide execution of stored procedures.

Class Definition

This is where the true complications start to occur – especially for disconnected or detached entities.  The Entity Framework is best used when a Data or Object context can remain instantiated and can subscribe to changes in entities which were created via the context .

Let’s take a look at what functionality is exposed by the generic class:

image
Figure 1 – The Obligatory Class Diagrams

Under the hood

To reduce the repetitiveness, I’ve combined “Insert” and “Update” into a single call (InsertOrUpdate) since the onus is on the calling code to have set the Object State for each entity correctly anyway.  That leaves us with Select, CreateQuery/GetEntities/GetEntity for reads and Delete for deletions. 

This hasn’t changed much since the earlier versions, but what *has* changed is how inserts, updates and deletes are handled by the class, behind the scenes.  The ApplyStateChanges (private) function has been refactored, and a chunk of functionality has been refactored into a separate function called ProcessEntityState.

Why refactor?  This makes the code a little more readable, and reduces the size of the ApplyStateChanges function so that it is responsible for processing.  There were also some changes to the way linked entities were handled in a many-to-one (or one-to-many) collection.

Changes to Entity Processing

Handling Object State

One big change I’ve made is how an entity set is handled when processing multiple entities.  The original implementation assumed that anything not local to the Data Context should be safely Attached, as per the below:

if (!ExistsLocal<T2>(item))
{
    dbSet.Attach(item);
}

if (item.State == ObjectState.Modified)
{
    dbSet.Attach(item);
}

However, after some more detailed testing, the code should respect the Object State which the calling code has applied to the entity (rather than relying solely on the Data Context’s local cache):

if (item.State == ObjectState.Modified)
{
    if (!ExistsLocal<T2>(item))
    {
        dbSet.Attach(item);
    }
}

Bug Fix: CreateQuery

A sample set of data I was using, went over the 100 row mark at one point, when I discovered a little faux par:

/// <summary> /// Allows freeform data queries from outside the Data Access classes,

/// without exposing the data context directly /// </summary> /// <returns>An IQueryable of type T - limited to 100 rows</returns> public IQueryable<T> CreateQuery() { IQueryable<T> _query = DataContext.Set<T>().AsQueryable<T>(); // _query = _query.Take(100); return _query; }

Applying the Take operation at this stage was actually restricting the query to the first 100 rows in the table, not restricting the final query to 100 rows.  Consequently, this was removed!

Finally

Let’s just jump right into the sample solution.  You can download a copy of the example solution

Please email me rob.sanders@sanderstechnology.com if you find any issues, have questions or leave a comment here…

Feb 232014
 
Advanced Twonky Media Server configuration on a Thecus NAS

Introduction As you’ll no doubt recall from my earlier 2012 article, I have a NAS in my home office.  It is a Thecus N5200XXX 5-bay Network Attached Storage device, and it sits on my home gigabit network. The Thecus features an OS which accommodates pluggable “modules”, one of which is a licensed copy of Twonky [...]

Feb 142014
 

Some exciting news to share – for those interested in pre-releases, the next iteration of the Entity Framework – v6.1.0 has been released as a Beta just recently (Feb 11th, 2014).  For those who are curious about the new features, check out this link or read the summary I’ve copied from that original article, below. [...]

Feb 132014
 
A lightweight implementation OWIN OAuth for ASP.NET Web Forms using Visual Studio 2013 – Part 3

Introduction In Part 1, we had a brief look at OWIN/OAuth concepts, and then prepared a clean ASP.NET web forms project for integration with NuGet packages essential to supporting a lightweight integration for OAuth handling. In Part 2  we established the information required to authenticate users against the Live Connect OAuth provider, and also established [...]

Feb 122014
 
A lightweight implementation OWIN OAuth for ASP.NET Web Forms using Visual Studio 2013 – Part 2

Introduction Where we left off in Part 1, we’d established the prerequisites to prepare either a new or existing web forms project for the implementation of a lightweight OWIN/OAuth provider. This article, Part 2, will focus on how to prepare your development environment and also how to configure for Windows Live Account authorisation. This article [...]