>I’ve modified Mikael Henriksson generic repository pattern to come up with simplified version. Below illustrate how you can use the generic repository without any or should i say 1 line of code.
IRepository.cs
///
/// Generic Repository Interface
///
public interface IRepository : IDisposable
{
///
/// Method to add new record to
///
///
///
///
bool Add
///
/// Method to delete record from
///
///
///
///
bool Delete
///
/// Method to update record from
///
///
///
///
bool Update
///
/// Returns new Transaction Scope
///
///
TransactionScope BeginTransaction();
///
/// Method to add new record to
/// You must manually call the CommitTransaction() so that changes will be reflected.
///
///
///
///
bool AddUsingTransaction
///
/// Method to delete record from
/// You must manually call the CommitTransaction() so that changes will be reflected.
///
///
///
///
bool DeleteUsingTransaction
///
/// Method to update record from
/// You must manually call the CommitTransaction() so that changes will be reflected.
///
///
///
///
bool UpdateUsingTransaction
///
/// Method that instructs the object context to accept all changes
///
void Commit();
///
/// Method that returns the count of
///
///
///
long Count
///
/// Method that returns the count of
///
///
///
///
long Count
///
/// Method to return all records from
///
///
///
List
///
/// Method to return all records from
///
///
///
///
List
///
/// Method to return the first record from
/// Throws an exception if there’s no result.
///
///
///
///
T GetSingle
///
/// Method to return the first record from
///
///
///
///
T GetSingleOrDefault
}
———————————-
DataRepositoryBase.cs
///
/// Generic Repository base class for Data Processing
///
public abstract class DataRepositoryBase : IRepository
{
protected ObjectContext mContext;
protected bool mContextReused;
///
/// Ctor
///
///
public DataRepositoryBase(ObjectContext context)
{
this.mContext = context;
}
///
/// Method to add new record to
///
///
///
///
public virtual bool Add
{
mContext.AddObject(mContext.GetEntitySet
int saveValue = mContext.SaveChanges();
return saveValue > 0 ? true: false;
}
///
/// Method to delete record from
///
///
///
///
public virtual bool Delete
{
object originalItem;
EntityKey key = mContext.CreateEntityKey(entity.EntityKey.EntitySetName, entity);
if (mContext.TryGetObjectByKey(key, out originalItem))
{
mContext.DeleteObject(originalItem);
}
int returnValue = mContext.SaveChanges();
return returnValue > 0 ? true : false;
}
///
/// Method to update record from
///
///
///
///
public virtual bool Update
{
object originalItem;
Type type = typeof(T);
EntityKey key = mContext.CreateEntityKey(entity.EntityKey.EntitySetName, entity);
if (mContext.TryGetObjectByKey(key, out originalItem))
{
mContext.ApplyCurrentValues(key.EntitySetName, entity);
}
int returnValue = mContext.SaveChanges();
return returnValue > 0 ? true : false;
}
///
/// Method to add new record to
///
///
///
///
public virtual bool AddUsingTransaction
{
mContext.AddObject(mContext.GetEntitySet
mContext.SaveChanges(SaveOptions.AcceptAllChangesAfterSave
SaveOptions.DetectChangesBeforeSave);
return true;
}
///
/// Method to delete record from
///
///
///
///
public virtual bool DeleteUsingTransaction
{
object originalItem;
EntityKey key = mContext.CreateEntityKey(entity.EntityKey.EntitySetName, entity);
if (mContext.TryGetObjectByKey(key, out originalItem))
{
mContext.DeleteObject(originalItem);
}
mContext.SaveChanges(SaveOptions.AcceptAllChangesAfterSave
SaveOptions.DetectChangesBeforeSave);
return true;
}
///
/// Method to update record from
///
///
///
///
public virtual bool UpdateUsingTransaction
{
object originalItem;
Type type = typeof(T);
EntityKey key = mContext.CreateEntityKey(entity.EntityKey.EntitySetName, entity);
if (mContext.TryGetObjectByKey(key, out originalItem))
{
mContext.ApplyCurrentValues(key.EntitySetName, entity);
}
mContext.SaveChanges(SaveOptions.AcceptAllChangesAfterSave
SaveOptions.DetectChangesBeforeSave);
return true;
}
public virtual void Commit()
{
mContext.AcceptAllChanges();
}
///
/// Method that returns the count of
///
///
///
public virtual long Count
{
int count = mContext.CreateQuery
return count;
}
///
/// Method that returns the count of
///
///
///
///
public virtual long Count
{
int count = mContext.CreateQuery
return count;
}
///
/// Method to return all records from
///
///
///
public virtual List
{
var entities = mContext.CreateQuery
return entities;
}
///
/// Method to return all records from
///
///
///
///
public virtual List
{
var entities = mContext.CreateQuery
return entities;
}
///
/// Method to return the first record from
/// Throws an exception if there’s no result.
///
///
///
///
public virtual T GetSingle
{
T entity = mContext.CreateQuery
return entity;
}
///
/// Method to return the first record from
///
///
///
///
public virtual T GetSingleOrDefault
{
T entity = mContext.CreateQuery
return entity;
}
///
/// Method for dispose
///
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (mContext != null)
{
mContext.Dispose();
mContext = null;
}
}
}
///
/// Returns new Transaction Scope
///
///
public System.Transactions.TransactionScope BeginTransaction()
{
return new System.Transactions.TransactionScope();
}
————————————–
ObjectContextExtension.cs
///
/// Object Context Extension Methods
///
public static class ObjectContextExtensions
{
///
/// Extension method for retrieving the EntitySetBase of
///
///
///
///
internal static EntitySetBase GetEntitySet
{
EntityContainer container = context.MetadataWorkspace.GetEntityContainer(context.DefaultContainerName, DataSpace.CSpace);
Type baseType = GetBaseType(typeof(TEntity));
EntitySetBase entitySet = container.BaseEntitySets.Where(item => item.ElementType.Name.Equals(baseType.Name)).FirstOrDefault(); return entitySet;
}
///
/// Method that returns the base type of
///
///
///
private static Type GetBaseType(Type type)
{
var baseType = type.BaseType;
if (baseType != null && baseType != typeof(EntityObject))
{
return GetBaseType(type.BaseType);
}
return type;
}
}
—————————
This is sample implementation of the Repository.You need to create two class, one class that inherits from DataRepositoryBase (Actual repository) and another that implements IRepository (Test Repository). Of course
you need to have a model that is created using Entity Framework in .NET 4.0.
Actual Repository:
public class MySampleActualRepository : DataRepositoryBase
{
public MySampleActualRepository()
: base(new MyCustomEntities())
{
}
}
Short code right?, you only need to pass the object context of EF to the base.
Test Repository:
Create a class MySampleTestRepository that implements IRepository’, I’m not going to show it here but you get the idea right? You can use my previous post especially in the GetAll() method since it’s returning a generic list.
With this two classes in place i think we are ready to try.
Create another method that would return the repository to be used.
public IRepository GetRepository (bool isTest)
{
if(isTest)
return new MySampleTestRepository();
else
return new MySampleActualRepository();
}
Sample usage:
using (IRepository repository = GetRepository(false))
{
//Add
DataEntities.Order order = new DataEntities.Order
{
order_ponumber = “00001”;
};
repository.Add(order);
//Update
var search = repository.GetSingleOrDefault
search.change_date = DateTime.Now;
repository.Update(search);
//Delete
repository.Delete(search);
}
Sample usage with Transaction Scope:
bool isCommit = false;
using (IRepository repository = GetRepository(false))
{
using(TransactionScope transactionScope = repository.BeginTransaction())
{
//Update
var search = repository.GetSingleOrDefault
search.change_date = DateTime.Now;
repository.UpdateUsingTransaction(search);
//Update # 2
var search2 = repository.GetSingleOrDefault
search2.change_date = DateTime.Now;
repository.UpdateUsingTransaction(search);
isCommit = true;
if(isCommit)
{
transactionScope.Complete();
repository.Commit();
}
}
}
If the update #2 failed, the changes in update #1 will be rollback.
Finally, when building new solution you never need to code the DataComponents part just create the model (EF) then create two class that inherits from DataRepositoryBase and IRepository respectively and it’s done.