Implementing Repository Pattern With Entity Framework

Posted on June 10, 2009. Filed under: Entity Framework |

Click here to Get the Sample code of Repository Implementation

My Recent published article in CodeProject is also available here in my blog post for those my friends who feels a little interest(!!) to read my blog post.

The Repository pattern is defined by P of EAA as:

Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.

Repository provides a in-memory like collection interface for accessing domain objects. So as far as the consuming component is concerned, it uses the repository just like a collection when working with Domain objects. The repository then neatly abstracts the internal mechanics of how the Add / Remove calls to the repository translate to the actual data access calls to the data store. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers.

So with the repository we get a nice abstraction that provides us with persistence ignorance and a nice separation of concerns where the responsibility of persisting domain objects is encapsulated by the Repository that  leaving the domain objects to deal entirely with the domain model and domain logic.

Here I use the Composite Repository pattern.

/// <summary>
/// Repository Interface defines the base
/// functionality required by all Repositories.
/// </summary>
/// <typeparam name="T">
/// The entity type that requires a Repository.
/// </typeparam>
public interface IRepository<E, C>
{
    DbTransaction BeginTransaction();
    void Add(E entity);
    void AddOrAttach(E entity);
    void DeleteRelatedEntries(E entity);
    void DeleteRelatedEntries(E entity, ObservableCollection<string> keyListOfIgnoreEntites);
    void Delete(E entity);
    int Save();

    ObjectQuery<E> DoQuery(string entitySetName);
    ObjectQuery<E> DoQuery();
    ObjectQuery<E> DoQuery(string entitySetName, ISpecification<E> where);
    ObjectQuery<E> DoQuery(ISpecification<E> where);
    ObjectQuery<E> DoQuery(int maximumRows, int startRowIndex);
    ObjectQuery<E> DoQuery<T>(Expression<Func<E, T>> sortExpression);
    ObjectQuery<E> DoQuery<T>(Expression<Func<E, T>> sortExpression, int maximumRows, int startRowIndex);

    IList<E> SelectAll(string entitySetName);
    IList<E> SelectAll();
    IList<E> SelectAll(string entitySetName, ISpecification<E> where);
    IList<E> SelectAll(ISpecification<E> where);
    IList<E> SelectAll(int maximumRows, int startRowIndex);
    IList<E> SelectAll<T>(Expression<Func<E, T>> sortExpression);
    IList<E> SelectAll<T>(Expression<Func<E, T>> sortExpression, int maximumRows, int startRowIndex);

    E SelectByKey(string Key);

    bool TrySameValueExist(string fieldName, object fieldValue, string key);
    bool TryEntity(ISpecification<E> selectSpec);

    int GetCount();
    int GetCount(ISpecification<E> selectSpec);
}

You can write your own Repository for each business object like RoleReporitosy, UserReporsitory etc etc…or You can Implement this interface as a generic somthing like this -

public class Repository<E, C> : IRepository<E, C>, IDisposable
    where E : EntityObject
    where C : ObjectContext
{
    private readonly C _ctx;

    private string _KeyProperty = "ID";

    public string KeyProperty
    {
        get
        {
            return _KeyProperty;
        }
        set
        {
            _KeyProperty = value;
        }
    }

    public C Session
    {
        get { return _ctx; }
    }

    public Repository(C session)
    {
        _ctx = session;
    }

    #region IRepository<E,C> Members

    public int Save()
    {
        return _ctx.SaveChanges();
    }
    /// <summary>
    /// A generic method to return ALL the entities
    /// of type TEntity. This overload will use the
    /// the parameter entitySetName in the resolution of mapping
    /// between the CSDL and SSDL. In Version
    /// 2.0 this pluralizing behaviour will change and this
    /// method overload should be used only if Developers
    /// change EntitySet names from the default name generated.
    /// </summary>
    /// <param name=”entitySetName”>
    /// The EntitySet name of the entity in the model.
    /// </param>
    /// <typeparam name=”TEntity”>
    /// The Entity to load from the database.
    /// </typeparam>
    /// <returns>Returns a set of TEntity.</returns>
    public ObjectQuery<E> DoQuery(string entitySetName)
    {
        return _ctx.CreateQuery<E>("[" + entitySetName + "]");
    }
    /// <summary>
    /// A generic method to return ALL the entities
    /// of type TEntity. This overload will use the
    /// typeof(TEntity).Name in the resolution of mapping
    /// between the CSDL and SSDL. This method is useful
    /// for Models that DO NOT have their pluralized names
    /// changed by the developer.
    /// </summary>
    /// <typeparam name=”TEntity”>
    /// The Entity to load from the database.
    /// </typeparam>
    /// <returns>Returns a set of TEntity.</returns>
    public ObjectQuery<E> DoQuery()
    {
        return _ctx.CreateQuery<E>("[" + typeof(E).Name + "]");
    }

    /// <summary>
    /// A generic method to return ALL the entities
    /// of type TEntity. This overload will use the
    /// the parameter entitySetName in the resolution of mapping
    /// between the CSDL and SSDL. This method is useful
    /// for Models that DO have their pluralized names
    /// changed by the developer.
    /// </summary>
    /// <param name=”entitySetName”>
    /// The EntitySet name of the entity in the model.
    /// </param>
    /// <typeparam name=”TEntity”>
    /// The Entity to load from the database.
    /// </typeparam>
    /// <returns>Returns a set of TEntity.</returns>
    public ObjectQuery<E> DoQuery(string entitySetName, ISpecification<E> where)
    {
        return
            (ObjectQuery<E>)_ctx.CreateQuery<E>("[" + entitySetName + "]")
            .Where(where.EvalPredicate);
    }

    /// <summary>
    /// A generic method to return ALL the entities
    /// of type TEntity. This overload will use the
    /// typeof(TEntity).Name in the resolution of mapping
    /// between the CSDL and SSDL. This method is useful
    /// for Models that DO NOT have their pluralized names
    /// changed by the developer.
    /// </summary>
    /// <typeparam name=”TEntity”>
    /// The Entity to load from the database.
    /// </typeparam>
    /// <returns>Returns a set of TEntity.</returns>
    public ObjectQuery<E> DoQuery(ISpecification<E> where)
    {
        return
            (ObjectQuery<E>)_ctx.CreateQuery<E>("[" + typeof(E).Name + "]")
            .Where(where.EvalPredicate);
    }
    /// <summary>
    /// Query Entity with Paging
    /// </summary>
    /// <param name="maximumRows">Max no of row to Fetch</param>
    /// <param name="startRowIndex">Start Index</param>
    /// <returns>Collection of Entities</returns>
    public ObjectQuery<E> DoQuery(int maximumRows, int startRowIndex)
    {
        return (ObjectQuery<E>)_ctx.CreateQuery<E>("[" + typeof(E).Name + "]").Skip<E>(startRowIndex).Take(maximumRows);
    }
    /// <summary>
    /// Query Entity in sorted Order
    /// </summary>
    /// <param name="sortExpression">Sort Expression/condition</param>
    /// <param name="ErrorCode">custom Error Message</param>
    /// <returns>Collection of Entities</returns>
    public ObjectQuery<E> DoQuery<T>(Expression<Func<E, T>> sortExpression)
    {
        if (null == sortExpression)
        {
            return ((IRepository<E, C>)this).DoQuery();
        }
        return (ObjectQuery<E>)((IRepository<E, C>)this).DoQuery().OrderBy<E, T>(sortExpression);
    }
    /// <summary>
    /// Query All Entity in sorted Order with Paging support
    /// </summary>
    /// <param name="sortExpression">Sort Expression/condition</param>
    /// <param name="maximumRows">Max no of row to Fetch</param>
    /// <param name="startRowIndex">Start Index</param>
    /// <returns>Collection Of entites</returns>
    public ObjectQuery<E> DoQuery<T>(Expression<Func<E, T>> sortExpression, int maximumRows, int startRowIndex)
    {
        if (sortExpression == null)
        {
            return ((IRepository<E, C>)this).DoQuery(maximumRows, startRowIndex);
        }
        return (ObjectQuery<E>)((IRepository<E, C>)this).DoQuery(sortExpression).Skip<E>(startRowIndex).Take(maximumRows);
    }
    /// <summary>
    /// A generic method to return ALL the entities
    /// of type TEntity. This overload will use the
    /// the parameter entitySetName in the resolution of mapping
    /// between the CSDL and SSDL. In Version
    /// 2.0 this pluralizing behaviour will change and this
    /// method overload should be used only if Developers
    /// change EntitySet names from the default name generated.
    /// </summary>
    /// <param name=”entitySetName”>
    /// The EntitySet name of the entity in the model.
    /// </param>
    /// <typeparam name=”TEntity”>
    /// The Entity to load from the database.
    /// </typeparam>
    /// <returns>Returns a set of TEntity.</returns>
    public IList<E> SelectAll(string entitySetName)
    {
        return DoQuery(entitySetName).ToList();
    }
    /// <summary>
    /// A generic method to return ALL the entities
    /// of type TEntity. This overload will use the
    /// typeof(TEntity).Name in the resolution of mapping
    /// between the CSDL and SSDL. This method is useful
    /// for Models that DO NOT have their pluralized names
    /// changed by the developer.
    /// </summary>
    /// <typeparam name=”TEntity”>
    /// The Entity to load from the database.
    /// </typeparam>
    /// <returns>Returns a set of TEntity.</returns>
    public IList<E> SelectAll()
    {
        try
        {
            return DoQuery().ToList(); //_ctx.CreateQuery<E>("[" + typeof(E).Name + "]");
        }
        catch (Exception)
        {
            throw;
        }
    }

    /// <summary>
    /// A generic method to return ALL the entities
    /// of type TEntity. This overload will use the
    /// the parameter entitySetName in the resolution of mapping
    /// between the CSDL and SSDL. This method is useful
    /// for Models that DO have their pluralized names
    /// changed by the developer.
    /// </summary>
    /// <param name=”entitySetName”>
    /// The EntitySet name of the entity in the model.
    /// </param>
    /// <typeparam name=”TEntity”>
    /// The Entity to load from the database.
    /// </typeparam>
    /// <returns>Returns a set of TEntity.</returns>
    public IList<E> SelectAll(string entitySetName, ISpecification<E> where)
    {
        return DoQuery(entitySetName, where).ToList();
    }

    /// <summary>
    /// A generic method to return ALL the entities
    /// of type TEntity. This overload will use the
    /// typeof(TEntity).Name in the resolution of mapping
    /// between the CSDL and SSDL. This method is useful
    /// for Models that DO NOT have their pluralized names
    /// changed by the developer.
    /// </summary>
    /// <typeparam name=”TEntity”>
    /// The Entity to load from the database.
    /// </typeparam>
    /// <returns>Returns a set of TEntity.</returns>
    public IList<E> SelectAll(ISpecification<E> where)
    {
        return DoQuery(where).ToList();
    }
    /// <summary>
    /// Select All Entity with Paging
    /// </summary>
    /// <param name="maximumRows">Max no of row to Fetch</param>
    /// <param name="startRowIndex">Start Index</param>
    /// <returns>Collection of Entities</returns>
    public IList<E> SelectAll(int maximumRows, int startRowIndex)
    {
        return DoQuery(maximumRows, startRowIndex).ToList();
    }
    /// <summary>
    /// Select All Entity in sorted Order
    /// </summary>
    /// <param name="sortExpression">Sort Expression/condition</param>
    /// <param name="ErrorCode">custom Error Message</param>
    /// <returns>Collection of Entities</returns>
    public IList<E> SelectAll<T>(Expression<Func<E, T>> sortExpression)
    {
        if (null == sortExpression)
        {
            return DoQuery(sortExpression).ToList();
        }
        return DoQuery(sortExpression).ToList();
    }
    /// <summary>
    /// Select All Entity in sorted Order with Paging support
    /// </summary>
    /// <param name="sortExpression">Sort Expression/condition</param>
    /// <param name="maximumRows">Max no of row to Fetch</param>
    /// <param name="startRowIndex">Start Index</param>
    /// <returns>Collection Of entites</returns>
    public IList<E> SelectAll<T>(Expression<Func<E, T>> sortExpression, int maximumRows, int startRowIndex)
    {
        if (sortExpression == null)
        {
            return DoQuery(maximumRows, startRowIndex).ToList();
        }
        return DoQuery(sortExpression, maximumRows, startRowIndex).ToList();
    }
    /// <summary>
    /// Get Entity By Primary Key
    /// </summary>
    /// <typeparam name="E">Entity Type</typeparam>
    /// <param name="Key">Primary Key Value</param>
    /// <returns>return entity</returns>
    public E SelectByKey(string Key)
    {
        // First we define the parameter that we are going to use the clause.
        var xParam = Expression.Parameter(typeof(E), typeof(E).Name);
        MemberExpression leftExpr = MemberExpression.Property(xParam, this._KeyProperty);
        Expression rightExpr = Expression.Constant(Key);
        BinaryExpression binaryExpr = MemberExpression.Equal(leftExpr, rightExpr);
        //Create Lambda Expression for the selection
        Expression<Func<E, bool>> lambdaExpr = Expression.Lambda<Func<E, bool>>(binaryExpr, new ParameterExpression[] { xParam });
        //Searching ....
        IList<E> resultCollection = ((IRepository<E, C>)this).SelectAll(new Specification<E>(lambdaExpr));
        if (null != resultCollection && resultCollection.Count() > 0)
        {
            //return valid single result
            return resultCollection.First<E>();
        }//end if
        return null;
    }
    /// <summary>
    /// Check if value of specific field is already exist
    /// </summary>
    /// <typeparam name="E"></typeparam>
    /// <param name="fieldName">name of the Field</param>
    /// <param name="fieldValue">Field value</param>
    /// <param name="key">Primary key value</param>
    /// <returns>True or False</returns>
    public bool TrySameValueExist(string fieldName, object fieldValue, string key)
    {
        // First we define the parameter that we are going to use the clause.
        var xParam = Expression.Parameter(typeof(E), typeof(E).Name);
        MemberExpression leftExprFieldCheck = MemberExpression.Property(xParam, fieldName);
        Expression rightExprFieldCheck = Expression.Constant(fieldValue);
        BinaryExpression binaryExprFieldCheck = MemberExpression.Equal(leftExprFieldCheck, rightExprFieldCheck);

        MemberExpression leftExprKeyCheck = MemberExpression.Property(xParam, this._KeyProperty);
        Expression rightExprKeyCheck = Expression.Constant(key);
        BinaryExpression binaryExprKeyCheck = MemberExpression.NotEqual(leftExprKeyCheck, rightExprKeyCheck);
        BinaryExpression finalBinaryExpr = Expression.And(binaryExprFieldCheck, binaryExprKeyCheck);

        //Create Lambda Expression for the selection
        Expression<Func<E, bool>> lambdaExpr = Expression.Lambda<Func<E, bool>>(finalBinaryExpr, new ParameterExpression[] { xParam });
        //Searching ....
        return ((IRepository<E, C>)this).TryEntity(new Specification<E>(lambdaExpr));
    }
    /// <summary>
    /// Check if Entities exist with Condition
    /// </summary>
    /// <param name="selectExpression">Selection Condition</param>
    /// <returns>True or False</returns>
    public bool TryEntity(ISpecification<E> selectSpec)
    {
        return _ctx.CreateQuery<E>("[" + typeof(E).Name + "]").Any<E>(selectSpec.EvalPredicate);
    }
    /// <summary>
    /// Get Count of all records
    /// </summary>
    /// <typeparam name="E"></typeparam>
    /// <returns>count of all records</returns>
    public int GetCount()
    {
        return _ctx.CreateQuery<E>("[" + typeof(E).Name + "]").Count();
    }
    /// <summary>
    /// Get count of selection
    /// </summary>
    /// <typeparam name="E">Selection Condition</typeparam>
    /// <returns>count of selection</returns>
    public int GetCount(ISpecification<E> selectSpec)
    {
        return _ctx.CreateQuery<E>("[" + typeof(E).Name + "]")
            .Where(selectSpec.EvalPredicate).Count();
    }
    /// <summary>
    /// Delete data from context
    /// </summary>
    /// <typeparam name="E"></typeparam>
    /// <param name="entity"></param>
    public void Delete(E entity)
    {
        _ctx.DeleteObject(entity);
    }
    /// <summary>
    /// Insert new data into context
    /// </summary>
    /// <typeparam name="E"></typeparam>
    /// <param name="entity"></param>
    public void Add(E entity)
    {
        _ctx.AddObject(entity.GetType().Name, entity);
    }
    /// <summary>
    /// Insert if new otherwise attach data into context
    /// </summary>
    /// <param name="entity"></param>
    public void AddOrAttach(E entity)
    {
        // Define an ObjectStateEntry and EntityKey for the current object.
        EntityKey key;
        object originalItem;
        // Get the detached object's entity key.
        if (entity.EntityKey == null)
        {
            // Get the entity key of the updated object.
            key = _ctx.CreateEntityKey(entity.GetType().Name, entity);
        }
        else
        {
            key = entity.EntityKey;
        }
        try
        {
            // Get the original item based on the entity key from the context
            // or from the database.
            if (_ctx.TryGetObjectByKey(key, out originalItem))
            {//accept the changed property
                if (originalItem is EntityObject &&
                    ((EntityObject)originalItem).EntityState != EntityState.Added)
                {
                    // Call the ApplyPropertyChanges method to apply changes
                    // from the updated item to the original version.
                    _ctx.ApplyPropertyChanges(
                        key.EntitySetName, entity);
                }
            }
            else
            {//add the new entity
                Add(entity);
            }//end else
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    /// <summary>
    /// Start Transaction
    /// </summary>
    /// <returns></returns>
    public DbTransaction BeginTransaction()
    {
        if (_ctx.Connection.State != ConnectionState.Open)
        {
            _ctx.Connection.Open();
        }
        return _ctx.Connection.BeginTransaction();
    }
    /// <summary>
    /// Delete all realted entries
    /// </summary>
    /// <param name="entity"></param>
    public void DeleteRelatedEntries(E entity)
    {
        foreach (var relatedEntity in (((IEntityWithRelationships)entity).RelationshipManager.GetAllRelatedEnds().SelectMany(re => re.CreateSourceQuery().OfType<EntityObject>()).Distinct()).ToArray())
        {
            _ctx.DeleteObject(relatedEntity);
        }//end foreach
    }
    /// <summary>
    /// Delete all realted entries
    /// </summary>
    /// <param name="entity"></param>
    public void DeleteRelatedEntries(E entity, ObservableCollection<string> keyListOfIgnoreEntites)
    {
        foreach (var relatedEntity in (((IEntityWithRelationships)entity).RelationshipManager.GetAllRelatedEnds().SelectMany(re => re.CreateSourceQuery().OfType<EntityObject>()).Distinct()).ToArray())
        {
            PropertyInfo propInfo = relatedEntity.GetType().GetProperty(this._KeyProperty);
            if (null != propInfo)
            {
                string value = (string)propInfo.GetValue(relatedEntity, null);
                if (!string.IsNullOrEmpty(value) &&
                    keyListOfIgnoreEntites.Contains(value))
                {
                    continue;
                }//end if
            }//end if
            _ctx.DeleteObject(relatedEntity);
        }//end foreach
    }

    #endregion

    #region IDisposable Members

    public void Dispose()
    {
        if (null != _ctx)
        {
            _ctx.Dispose();
        }
    }

    #endregion

}

Notice that , Here I also implement IDicpose interface to dispose the context manually.To get the name of Entityset, Here I have used typeof  ,but you can you metadata query to retrieve the entityset name.

var container = context.MetadataWorkspace.GetEntityContainer(context.DefaultContainerName, DataSpace.CSpace);
string entitySetName = (from meta in container.BaseEntitySets
                        where meta.ElementType.Name == entityTypeName
                        select meta.Name).FirstOrDefault();

Here I am not gointo the code. 

The specification pattern we can implement a re-usable business logic component that can be passed around to satisfy certain business criteria . The specification object has a clear and limited responsibility, which can be separated and decoupled from the domain object that uses it. I would highly recommend reading the white paper by Martin Fowler and Eric Evans on the Specification pattern. 

public interface ISpecification<E>
{
    /// <summary>
    /// Select/Where Expression
    /// </summary>
    Expression<Func<E, bool>> EvalPredicate { get; }
    /// <summary>
    /// Function to evaluate where Expresiion
    /// </summary>
    Func<E, bool> EvalFunc { get; }
}

You can write your own specification by implementing your interface like RoleSpecification and put down your business logic there.For general use you can also Implement this composite specification interface like this-

public class Specification<E> : ISpecification<E>
{
    #region Private Members

    private Func<E, bool> _evalFunc = null;
    private Expression<Func<E, bool>> _evalPredicate;

    #endregion

    #region Virtual Accessors

    public virtual Expression<Func<E, bool>> EvalPredicate
    {
        get { return _evalPredicate; }
    }

    public virtual Func<E, bool> EvalFunc
    {
        get { return _evalFunc; }
    }

    #endregion

    #region Constructors

    public Specification(Expression<Func<E, bool>> predicate)
    {
        _evalPredicate = predicate;
    }

    private Specification() { }

    #endregion
}

To use this Repository and Specification class from your business layer, one thing I must have to say that I am sharing a single context in the CRUD process/operation. You must keep alive the context in your entire process of a crud operation. For this I make a Global variable of my EF ObjectContext and   all using repository and in the constructor I initialize all this variables like this-

#region Global members

Repository< User, SecurityEntities> _userRepository = null;
Repository< Role, SecurityEntities> _roleRepository = null;
Repository< Task, JerichoSecurityEntities> _taskRepository = null;
Repository< RoleInUser,SecurityEntities> _roleInUserRepository
         = null;
Repository< RoleTask,SecurityEntities> _roleTaskRepository
         = null;
Repository< DBAuditForSecurity, SecurityEntities> _securityAuditRepository

SecurityEntities _ctx = null;
#endregion

public BLLRoleManagement()
{
    _ctx = Helper.SecurityContextInstance;
    _userRepository = new Repository< User,SecurityEntities>(_ctx);
    _roleRepository = new Repository< Role, SecurityEntities>(_ctx);
    _taskRepository = new Repository< Task, SecurityEntities>(_ctx);
    _roleInUserRepository = new Repository< RoleInUser, SecurityEntities>(_ctx);
    _roleTaskRepository = new Repository< RoleTask, SecurityEntities>(_ctx);
    _securityAuditRepository = new Repository< DBAuditForSecurity, SecurityEntities>(_ctx);
}
………………………….
……………………………………………

Now In my BLLRoleManagement, say I have method to delete User. That will be something like this –

/// <summary>
/// Delete User
/// </summary>
/// <param name="userID">User ID</param>
/// <returns>True Or False</returns>
public static bool DeleteUser(
    string UserID)
{
    try
    {
        using (DbTransaction transaction = userRepository.BeginTransaction())
        {
            User UserTobeRemoved = userRepository.SelectByKey(UserID);
            if (UserTobeRemoved == null)
                return false;

            userRepository.DeleteRelatedEntries(UserTobeRemoved);
            userRepository.Delete(UserTobeRemoved);
            if (userRepository.Save() >= 0)
            {
                transaction.Commit();
                return true;
            }
        }
    }
    catch (Exception ex)
    {
        throw ErrorHandler.WrapException(ex, ErrorCodes.DB_DeleteUser_Error_Code);
    }
    return false;
}

So You can call this method like –

new BLLRoleManagement().DeleteUser(userID);

Advertisement

Make a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

5 Responses to “Implementing Repository Pattern With Entity Framework”

RSS Feed for Morshed Anwar's Blog Comments RSS Feed

Hi

Can you, please, change the sample and using POCO with EF4. There is not good samples in the red and your code is good for one sample of POCO Entities.

Thanx for ur comments. Ok , very recently I will make a blog post on working with POCO and EF and will use repository pattern there.

HI

Where is the sample of Repository using EF4 and POCO ???

First, this is a great starting reference for Repository patterns. I have modified your repository to support POCO and have tested and works nice.

Second, I have a question about using static methods such as
public static Setting GetSettingByID(int settingID)
{
return (Setting)settingsRepo.Single(p=>p.SettingID == settingID)
}
my class is structured as
public class SettingBLL
{
private static Repository settingsRepo;
static SettingBLL()
{
EntityModel db = new EntityModel();
settingsRepo = new Repository(db);
}

public static Setting GetSettingByID(Int32 settingID)
{
return (Setting)settingsRepo.Single(param => param.SettingID == settingID);
}
}
As you know, you mention that the context lifetime should be kept as long as the class/BLL workflow will be executed. Then the context should be disposed with the implementation of IDisposable. But this is in a case when we instantiate the class, and not the case when we have static methods. So i had to abandon the Dispose because later in the front end code a if a call is made again to the SettingBLL, the current that executed is disposed and since i am calling a static method the class will not be constructed again, nor the context will be kept alive for long enough.

Are there any implications of using the repository pattern as such, will it consume more memory, what will be the performance issues that i can expect?

Thanks, Martin.

[...] two years ago have written a post and an article in code project about the repository pattern implementation with EF V1. After that I [...]


Where's The Comment Form?

Liked it here?
Why not try sites on the blogroll...

Follow

Get every new post delivered to your Inbox.