Tuesday, March 26, 2013

Are you using Entity Framework? DRY!

I'm not a big fan of Entity Framework... I don't use Model First with some tables mapped into an .edmx or Code First... My usage of EF is prety simple: I work with stored procedures and EF saves me time (a lot...) on the code which uses my stored procedures.

Going back to my title: "Are you using Entity Framework? DRY!" Why "Don't Repeat Yourself"? Because a lot of people repeat the same lines of code:


   1:  [...]
   2:   
   3:  int count;
   4:   
   5:  using (var db = new xxxEntities())
   6:  {
   7:       count = db.OneTable.Count();
   8:  }
   9:   
  10:  [...]

As you know, the using statement is very important (if you don't know why, don't hesitate to do some research) but it is not a reason to repeat yourself!

The line using (var db = new xxxEntities()) will be in each of your calls to the database (and maybe more redundant code like a call to a retry policy...)!

A good solution is to use an unique place where you put your using statement (and other redundant stuff):


   1:  using System;
   2:  using System.Data.Entity;
   3:  using System.Transactions;
   4:   
   5:  namespace Admin.Persistence.Repositories.Impl
   6:  {
   7:      public class Repository
   8:      {
   9:          protected TK Execute<T, TK>(Func<T, TK> f) where T : DbContext, new()
  10:          {
  11:              TK result;
  12:   
  13:              using (var db = new T())
  14:              {
  15:                  result = f(db);
  16:              }
  17:   
  18:              return result;
  19:          }  
  20:      }
  21:  }

Here is an exemple of an utilisation of the previous class:


   1:  using System.Data.Objects;
   2:  using Admin.Persistence.Data;
   3:   
   4:  namespace Admin.Persistence.Repositories.Impl
   5:  {
   6:      public sealed class TenantFurnisherRepository : Repository, ITenantFurnisherRepository
   7:      {
   8:          public long GetTenantId(string name)
   9:          {
  10:              var id = new ObjectParameter("id", typeof (long));
  11:   
  12:              Execute<TenantIdsFurnisherEntities, int>(ttif => ttif.GetTenantIdByName(name, id));
  13:   
  14:              return long.Parse(id.Value.ToString());
  15:          }
  16:   
  17:          public long RegisterTenant(string name)
  18:          {
  19:              var id = new ObjectParameter("id", typeof(long));
  20:   
  21:              Execute<TenantIdsFurnisherEntities, int>(ttif => ttif.RegisterTenant(name, id));
  22:   
  23:              return long.Parse(id.Value.ToString());
  24:          }
  25:      }
  26:  }

(note: the return value is not used in this case)

With that kind of code you can be more confortable in the maintenance of your code, etc. You can imagine to wrap your using statement with a retry policy for SQL Azure:


   1:  [...]
   2:   
   3:  SqlAzureRetryPolicy.ExecuteAction(() =>
   4:  {
   5:      using (var db = new T())
   6:      {
   7:          result = f(db);
   8:      }
   9:  });
  10:   
  11:  [...]

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.