The short example about Entity Framework 4 CTP4 - Part 2
Part 2: Repository and Unit of Work on Entity Framework 4
-
Create the repository for persistence ignorance
Up to now, I very love the Persistence Ignorance. So what is it? I remembered that I usually built the Data Access Layer for access Database in the past. That is make your layer is coupling with the Database. So it is not good if you change database, change something else. So what do you think if we don’t need to know about it? Just tell the class that “I want to make something, and don’t care what happen in the behind scene.” It’s really good, and that is a place where Repository pattern jumps into. For more information, go to http://martinfowler.com/eaaCatalog/repository.html. I don’t want to speak more about it. Now we shall continue on my example. The first thing, we must to build is a IRepository interface for making a contract.
public interface IRepository<T> where T : IEntity
{
}
IRepository is constraint on T generic type and must be an IEntity. Now I want to separate with 2 Repositories that do specific jobs. At here, I divided 2 Repositories with 2 contracts are: ICommandRepository and IQueryRepository. ICommandRepository contains all actions about CRUD, and IQueryRepository contains all actions about query data. That is it.
public interface ICommandRepository<T> : IRepository<T> where T : IEntity
{
/// <summary>
/// Gets the by id.
/// </summary>
/// <param name="id">The id.</param>
/// <returns></returns>
T GetById(int id);
/// <summary>
/// Adds the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
/// <returns></returns>
T Add(T entity);
/// <summary>
/// Updates the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
void Update(T entity);
/// <summary>
/// Deletes the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
void Delete(T entity);
/// <summary>
/// Deletes the specified id.
/// </summary>
/// <param name="id">The id.</param>
void Delete(int id);
/// <summary>
/// Units the of work.
/// </summary>
/// <returns></returns>
IUnitOfWork UnitOfWork();
}
And,
public interface IQueryRepository<T> : IRepository<T> where T : IEntity
{
/// <summary>
/// Gets all.
/// </summary>
/// <returns></returns>
IEnumerable<T> GetAll();
/// <summary>
/// Gets the specified where.
/// </summary>
/// <param name="where">The where.</param>
/// <returns></returns>
IEnumerable<T> Get(Func<T, bool> where);
}
I also have a base Repository for re-use all things that you think it can shared for all Repository used.
public abstract class BaseRepository<T> : IDisposable
{
private DbContext _dbContext;
/// <summary>
/// Initializes a new instance of the <see cref="BaseRepository<T>"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public BaseRepository(IDatabaseFactory databaseFactory)
{
Contract.Assert(databaseFactory != null, "DatabaseFactory is null");
DatabaseFactory = databaseFactory;
}
/// <summary>
/// Gets or sets the database factory.
/// </summary>
/// <value>The database factory.</value>
protected IDatabaseFactory DatabaseFactory
{
get;
private set;
}
/// <summary>
/// Gets the db context.
/// </summary>
/// <value>The db context.</value>
protected DbContext DbContext
{
[DebuggerStepThrough]
get
{
return _dbContext ?? (_dbContext = DatabaseFactory.Get());
}
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
if (DbContext != null)
GC.SuppressFinalize(DbContext);
if (DatabaseFactory != null)
GC.SuppressFinalize(DatabaseFactory);
}
}
Now we can implement the CategoryRepository as below:
public interface ICategoryRepository : ICommandRepository<Category>, IQueryRepository<Category>
{
}
public class CategoryRepository : BaseRepository<Category>, ICategoryRepository
{
/// <summary>
/// Initializes a new instance of the <see cref="CategoryRepository"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public CategoryRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
/// <summary>
/// Units the of work.
/// </summary>
/// <returns></returns>
public IUnitOfWork UnitOfWork()
{
return DbContext as CSPDbContext;
}
/// <summary>
/// Gets the by id.
/// </summary>
/// <param name="id">The id.</param>
/// <returns></returns>
public Category GetById(int id)
{
Contract.Assert(DbContext != null, "DbContext is null");
var temp = DbContext as CSPDbContext;
return (temp).Categories.Where<Category>(x => x.Id == id).FirstOrDefault<Category>();
}
/// <summary>
/// Adds the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
/// <returns></returns>
public Category Add(Category entity)
{
Contract.Assert(DbContext != null, "DbContext is null");
var temp = DbContext as CSPDbContext;
temp.Categories.Add(entity);
return entity;
}
...
}
Unit of Work on EF4
This is a hard pattern in EF4, so I will don’t explain about it. I just gave you a reference to read it, and I also implemented according to this link
http://blogs.msdn.com/b/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx
This is my code:
public interface IUnitOfWork
{
/// <summary>
/// Saves this instance.
/// </summary>
void Save();
}
public partial class CSPDbContext : DbContext, IUnitOfWork
{
...
/// <summary>
/// Saves this instance.
/// </summary>
public void Save()
{
SaveChanges();
}
}
I gave the CSPDbContext implementing the IUnitOfWork contract, and
public class CategoryRepository : BaseRepository<Category>, ICategoryRepository
{
/// <summary>
/// Initializes a new instance of the <see cref="CategoryRepository"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public CategoryRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
/// <summary>
/// Units the of work.
/// </summary>
/// <returns></returns>
public IUnitOfWork UnitOfWork()
{
return DbContext as CSPDbContext;
}
...
}
Now I do unit testing for CategoryRepository as:
[TestMethod()]
public void GetAllTesting()
{
var result = CategoryRepository.GetAll();
Assert.IsNotNull(result);
}
[TestMethod()]
public void AddCategoryTesting()
{
var entity = CategoryRepository.Add(new CallStoreProc.Data.Entity.Category()
{
Name = "test",
IsDelete = false,
CreatedDate = DateTime.Now,
Description = "test"
});
Assert.IsNotNull(entity);
Assert.AreEqual(entity.Name, "test");
Assert.AreEqual(entity.IsDelete, false);
}
Unit testing for UnitOfWork:
[TestMethod()]
public void UnitOfWorkTesting()
{
var uow = CategoryRepository.UnitOfWork();
var entity1 = CategoryRepository.Add(new CallStoreProc.Data.Entity.Category()
{
Name = "test3",
IsDelete = false,
CreatedDate = DateTime.Now,
Description = "test3"
});
var entity2 = CategoryRepository.Add(new CallStoreProc.Data.Entity.Category()
{
Name = "test4",
IsDelete = false,
CreatedDate = DateTime.Now,
Description = "test4"
});
uow.Save();
}
Part 1: Step up ADO.NET Entity Framework 4 CTP4
Part 3: Invoke store procedure in ADO.NET Entity Framework 4
Part 2: Repository and Unit of Work on Entity Framework 4
-
Create the repository for persistence ignorance
Up to now, I very love the Persistence Ignorance. So what is it? I remembered that I usually built the Data Access Layer for access Database in the past. That is make your layer is coupling with the Database. So it is not good if you change database, change something else. So what do you think if we don’t need to know about it? Just tell the class that “I want to make something, and don’t care what happen in the behind scene.” It’s really good, and that is a place where Repository pattern jumps into. For more information, go to http://martinfowler.com/eaaCatalog/repository.html. I don’t want to speak more about it. Now we shall continue on my example. The first thing, we must to build is a IRepository interface for making a contract.
public interface IRepository<T> where T : IEntity
{
}
IRepository is constraint on T generic type and must be an IEntity. Now I want to separate with 2 Repositories that do specific jobs. At here, I divided 2 Repositories with 2 contracts are: ICommandRepository and IQueryRepository. ICommandRepository contains all actions about CRUD, and IQueryRepository contains all actions about query data. That is it.
public interface ICommandRepository<T> : IRepository<T> where T : IEntity
{
/// <summary>
/// Gets the by id.
/// </summary>
/// <param name="id">The id.</param>
/// <returns></returns>
T GetById(int id);
/// <summary>
/// Adds the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
/// <returns></returns>
T Add(T entity);
/// <summary>
/// Updates the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
void Update(T entity);
/// <summary>
/// Deletes the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
void Delete(T entity);
/// <summary>
/// Deletes the specified id.
/// </summary>
/// <param name="id">The id.</param>
void Delete(int id);
/// <summary>
/// Units the of work.
/// </summary>
/// <returns></returns>
IUnitOfWork UnitOfWork();
}
And,
public interface IQueryRepository<T> : IRepository<T> where T : IEntity
{
/// <summary>
/// Gets all.
/// </summary>
/// <returns></returns>
IEnumerable<T> GetAll();
/// <summary>
/// Gets the specified where.
/// </summary>
/// <param name="where">The where.</param>
/// <returns></returns>
IEnumerable<T> Get(Func<T, bool> where);
}
I also have a base Repository for re-use all things that you think it can shared for all Repository used.
public abstract class BaseRepository<T> : IDisposable
{
private DbContext _dbContext;
/// <summary>
/// Initializes a new instance of the <see cref="BaseRepository<T>"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public BaseRepository(IDatabaseFactory databaseFactory)
{
Contract.Assert(databaseFactory != null, "DatabaseFactory is null");
DatabaseFactory = databaseFactory;
}
/// <summary>
/// Gets or sets the database factory.
/// </summary>
/// <value>The database factory.</value>
protected IDatabaseFactory DatabaseFactory
{
get;
private set;
}
/// <summary>
/// Gets the db context.
/// </summary>
/// <value>The db context.</value>
protected DbContext DbContext
{
[DebuggerStepThrough]
get
{
return _dbContext ?? (_dbContext = DatabaseFactory.Get());
}
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
if (DbContext != null)
GC.SuppressFinalize(DbContext);
if (DatabaseFactory != null)
GC.SuppressFinalize(DatabaseFactory);
}
}
Now we can implement the CategoryRepository as below:
public interface ICategoryRepository : ICommandRepository<Category>, IQueryRepository<Category>
{
}
public class CategoryRepository : BaseRepository<Category>, ICategoryRepository
{
/// <summary>
/// Initializes a new instance of the <see cref="CategoryRepository"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public CategoryRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
/// <summary>
/// Units the of work.
/// </summary>
/// <returns></returns>
public IUnitOfWork UnitOfWork()
{
return DbContext as CSPDbContext;
}
/// <summary>
/// Gets the by id.
/// </summary>
/// <param name="id">The id.</param>
/// <returns></returns>
public Category GetById(int id)
{
Contract.Assert(DbContext != null, "DbContext is null");
var temp = DbContext as CSPDbContext;
return (temp).Categories.Where<Category>(x => x.Id == id).FirstOrDefault<Category>();
}
/// <summary>
/// Adds the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
/// <returns></returns>
public Category Add(Category entity)
{
Contract.Assert(DbContext != null, "DbContext is null");
var temp = DbContext as CSPDbContext;
temp.Categories.Add(entity);
return entity;
}
...
}
Unit of Work on EF4
This is a hard pattern in EF4, so I will don’t explain about it. I just gave you a reference to read it, and I also implemented according to this link
http://blogs.msdn.com/b/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx
This is my code:
public interface IUnitOfWork
{
/// <summary>
/// Saves this instance.
/// </summary>
void Save();
}
public partial class CSPDbContext : DbContext, IUnitOfWork
{
...
/// <summary>
/// Saves this instance.
/// </summary>
public void Save()
{
SaveChanges();
}
}
I gave the CSPDbContext implementing the IUnitOfWork contract, and
public class CategoryRepository : BaseRepository<Category>, ICategoryRepository
{
/// <summary>
/// Initializes a new instance of the <see cref="CategoryRepository"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public CategoryRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
/// <summary>
/// Units the of work.
/// </summary>
/// <returns></returns>
public IUnitOfWork UnitOfWork()
{
return DbContext as CSPDbContext;
}
...
}
Now I do unit testing for CategoryRepository as:
[TestMethod()]
public void GetAllTesting()
{
var result = CategoryRepository.GetAll();
Assert.IsNotNull(result);
}
[TestMethod()]
public void AddCategoryTesting()
{
var entity = CategoryRepository.Add(new CallStoreProc.Data.Entity.Category()
{
Name = "test",
IsDelete = false,
CreatedDate = DateTime.Now,
Description = "test"
});
Assert.IsNotNull(entity);
Assert.AreEqual(entity.Name, "test");
Assert.AreEqual(entity.IsDelete, false);
}
Unit testing for UnitOfWork:
[TestMethod()]
public void UnitOfWorkTesting()
{
var uow = CategoryRepository.UnitOfWork();
var entity1 = CategoryRepository.Add(new CallStoreProc.Data.Entity.Category()
{
Name = "test3",
IsDelete = false,
CreatedDate = DateTime.Now,
Description = "test3"
});
var entity2 = CategoryRepository.Add(new CallStoreProc.Data.Entity.Category()
{
Name = "test4",
IsDelete = false,
CreatedDate = DateTime.Now,
Description = "test4"
});
uow.Save();
}
Part 1: Step up ADO.NET Entity Framework 4 CTP4
Part 3: Invoke store procedure in ADO.NET Entity Framework 4
{
}
IRepository is constraint on T generic type and must be an IEntity. Now I want to separate with 2 Repositories that do specific jobs. At here, I divided 2 Repositories with 2 contracts are: ICommandRepository and IQueryRepository. ICommandRepository contains all actions about CRUD, and IQueryRepository contains all actions about query data. That is it.
public interface ICommandRepository<T> : IRepository<T> where T : IEntity
{
/// <summary>
/// Gets the by id.
/// </summary>
/// <param name="id">The id.</param>
/// <returns></returns>
T GetById(int id);
/// <summary>
/// Adds the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
/// <returns></returns>
T Add(T entity);
/// <summary>
/// Updates the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
void Update(T entity);
/// <summary>
/// Deletes the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
void Delete(T entity);
/// <summary>
/// Deletes the specified id.
/// </summary>
/// <param name="id">The id.</param>
void Delete(int id);
/// <summary>
/// Units the of work.
/// </summary>
/// <returns></returns>
IUnitOfWork UnitOfWork();
}
And,
public interface IQueryRepository<T> : IRepository<T> where T : IEntity
{
/// <summary>
/// Gets all.
/// </summary>
/// <returns></returns>
IEnumerable<T> GetAll();
/// <summary>
/// Gets the specified where.
/// </summary>
/// <param name="where">The where.</param>
/// <returns></returns>
IEnumerable<T> Get(Func<T, bool> where);
}
I also have a base Repository for re-use all things that you think it can shared for all Repository used.
public abstract class BaseRepository<T> : IDisposable
{
private DbContext _dbContext;
/// <summary>
/// Initializes a new instance of the <see cref="BaseRepository<T>"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public BaseRepository(IDatabaseFactory databaseFactory)
{
Contract.Assert(databaseFactory != null, "DatabaseFactory is null");
DatabaseFactory = databaseFactory;
}
/// <summary>
/// Gets or sets the database factory.
/// </summary>
/// <value>The database factory.</value>
protected IDatabaseFactory DatabaseFactory
{
get;
private set;
}
/// <summary>
/// Gets the db context.
/// </summary>
/// <value>The db context.</value>
protected DbContext DbContext
{
[DebuggerStepThrough]
get
{
return _dbContext ?? (_dbContext = DatabaseFactory.Get());
}
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
if (DbContext != null)
GC.SuppressFinalize(DbContext);
if (DatabaseFactory != null)
GC.SuppressFinalize(DatabaseFactory);
}
}
Now we can implement the CategoryRepository as below:
public interface ICategoryRepository : ICommandRepository<Category>, IQueryRepository<Category>
{
}
public class CategoryRepository : BaseRepository<Category>, ICategoryRepository
{
/// <summary>
/// Initializes a new instance of the <see cref="CategoryRepository"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public CategoryRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
/// <summary>
/// Units the of work.
/// </summary>
/// <returns></returns>
public IUnitOfWork UnitOfWork()
{
return DbContext as CSPDbContext;
}
/// <summary>
/// Gets the by id.
/// </summary>
/// <param name="id">The id.</param>
/// <returns></returns>
public Category GetById(int id)
{
Contract.Assert(DbContext != null, "DbContext is null");
var temp = DbContext as CSPDbContext;
return (temp).Categories.Where<Category>(x => x.Id == id).FirstOrDefault<Category>();
}
/// <summary>
/// Adds the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
/// <returns></returns>
public Category Add(Category entity)
{
Contract.Assert(DbContext != null, "DbContext is null");
var temp = DbContext as CSPDbContext;
temp.Categories.Add(entity);
return entity;
}
...
}
Unit of Work on EF4
This is a hard pattern in EF4, so I will don’t explain about it. I just gave you a reference to read it, and I also implemented according to this link
http://blogs.msdn.com/b/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx
This is my code:
public interface IUnitOfWork
{
/// <summary>
/// Saves this instance.
/// </summary>
void Save();
}
public partial class CSPDbContext : DbContext, IUnitOfWork
{
...
/// <summary>
/// Saves this instance.
/// </summary>
public void Save()
{
SaveChanges();
}
}
I gave the CSPDbContext implementing the IUnitOfWork contract, and
public class CategoryRepository : BaseRepository<Category>, ICategoryRepository
{
/// <summary>
/// Initializes a new instance of the <see cref="CategoryRepository"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public CategoryRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
/// <summary>
/// Units the of work.
/// </summary>
/// <returns></returns>
public IUnitOfWork UnitOfWork()
{
return DbContext as CSPDbContext;
}
...
}
Now I do unit testing for CategoryRepository as:
[TestMethod()]
public void GetAllTesting()
{
var result = CategoryRepository.GetAll();
Assert.IsNotNull(result);
}
[TestMethod()]
public void AddCategoryTesting()
{
var entity = CategoryRepository.Add(new CallStoreProc.Data.Entity.Category()
{
Name = "test",
IsDelete = false,
CreatedDate = DateTime.Now,
Description = "test"
});
Assert.IsNotNull(entity);
Assert.AreEqual(entity.Name, "test");
Assert.AreEqual(entity.IsDelete, false);
}
Unit testing for UnitOfWork:
[TestMethod()]
public void UnitOfWorkTesting()
{
var uow = CategoryRepository.UnitOfWork();
var entity1 = CategoryRepository.Add(new CallStoreProc.Data.Entity.Category()
{
Name = "test3",
IsDelete = false,
CreatedDate = DateTime.Now,
Description = "test3"
});
var entity2 = CategoryRepository.Add(new CallStoreProc.Data.Entity.Category()
{
Name = "test4",
IsDelete = false,
CreatedDate = DateTime.Now,
Description = "test4"
});
uow.Save();
}
Part 1: Step up ADO.NET Entity Framework 4 CTP4
Part 3: Invoke store procedure in ADO.NET Entity Framework 4
{
/// <summary>
/// Gets the by id.
/// </summary>
/// <param name="id">The id.</param>
/// <returns></returns>
T GetById(int id);
/// <summary>
/// Adds the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
/// <returns></returns>
T Add(T entity);
/// <summary>
/// Updates the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
void Update(T entity);
/// <summary>
/// Deletes the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
void Delete(T entity);
/// <summary>
/// Deletes the specified id.
/// </summary>
/// <param name="id">The id.</param>
void Delete(int id);
/// <summary>
/// Units the of work.
/// </summary>
/// <returns></returns>
IUnitOfWork UnitOfWork();
}
And,
public interface IQueryRepository<T> : IRepository<T> where T : IEntity
{
/// <summary>
/// Gets all.
/// </summary>
/// <returns></returns>
IEnumerable<T> GetAll();
/// <summary>
/// Gets the specified where.
/// </summary>
/// <param name="where">The where.</param>
/// <returns></returns>
IEnumerable<T> Get(Func<T, bool> where);
}
I also have a base Repository for re-use all things that you think it can shared for all Repository used.
public abstract class BaseRepository<T> : IDisposable
{
private DbContext _dbContext;
/// <summary>
/// Initializes a new instance of the <see cref="BaseRepository<T>"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public BaseRepository(IDatabaseFactory databaseFactory)
{
Contract.Assert(databaseFactory != null, "DatabaseFactory is null");
DatabaseFactory = databaseFactory;
}
/// <summary>
/// Gets or sets the database factory.
/// </summary>
/// <value>The database factory.</value>
protected IDatabaseFactory DatabaseFactory
{
get;
private set;
}
/// <summary>
/// Gets the db context.
/// </summary>
/// <value>The db context.</value>
protected DbContext DbContext
{
[DebuggerStepThrough]
get
{
return _dbContext ?? (_dbContext = DatabaseFactory.Get());
}
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
if (DbContext != null)
GC.SuppressFinalize(DbContext);
if (DatabaseFactory != null)
GC.SuppressFinalize(DatabaseFactory);
}
}
Now we can implement the CategoryRepository as below:
public interface ICategoryRepository : ICommandRepository<Category>, IQueryRepository<Category>
{
}
public class CategoryRepository : BaseRepository<Category>, ICategoryRepository
{
/// <summary>
/// Initializes a new instance of the <see cref="CategoryRepository"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public CategoryRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
/// <summary>
/// Units the of work.
/// </summary>
/// <returns></returns>
public IUnitOfWork UnitOfWork()
{
return DbContext as CSPDbContext;
}
/// <summary>
/// Gets the by id.
/// </summary>
/// <param name="id">The id.</param>
/// <returns></returns>
public Category GetById(int id)
{
Contract.Assert(DbContext != null, "DbContext is null");
var temp = DbContext as CSPDbContext;
return (temp).Categories.Where<Category>(x => x.Id == id).FirstOrDefault<Category>();
}
/// <summary>
/// Adds the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
/// <returns></returns>
public Category Add(Category entity)
{
Contract.Assert(DbContext != null, "DbContext is null");
var temp = DbContext as CSPDbContext;
temp.Categories.Add(entity);
return entity;
}
...
}
Unit of Work on EF4
This is a hard pattern in EF4, so I will don’t explain about it. I just gave you a reference to read it, and I also implemented according to this link
http://blogs.msdn.com/b/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx
This is my code:
public interface IUnitOfWork
{
/// <summary>
/// Saves this instance.
/// </summary>
void Save();
}
public partial class CSPDbContext : DbContext, IUnitOfWork
{
...
/// <summary>
/// Saves this instance.
/// </summary>
public void Save()
{
SaveChanges();
}
}
I gave the CSPDbContext implementing the IUnitOfWork contract, and
public class CategoryRepository : BaseRepository<Category>, ICategoryRepository
{
/// <summary>
/// Initializes a new instance of the <see cref="CategoryRepository"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public CategoryRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
/// <summary>
/// Units the of work.
/// </summary>
/// <returns></returns>
public IUnitOfWork UnitOfWork()
{
return DbContext as CSPDbContext;
}
...
}
Now I do unit testing for CategoryRepository as:
[TestMethod()]
public void GetAllTesting()
{
var result = CategoryRepository.GetAll();
Assert.IsNotNull(result);
}
[TestMethod()]
public void AddCategoryTesting()
{
var entity = CategoryRepository.Add(new CallStoreProc.Data.Entity.Category()
{
Name = "test",
IsDelete = false,
CreatedDate = DateTime.Now,
Description = "test"
});
Assert.IsNotNull(entity);
Assert.AreEqual(entity.Name, "test");
Assert.AreEqual(entity.IsDelete, false);
}
Unit testing for UnitOfWork:
[TestMethod()]
public void UnitOfWorkTesting()
{
var uow = CategoryRepository.UnitOfWork();
var entity1 = CategoryRepository.Add(new CallStoreProc.Data.Entity.Category()
{
Name = "test3",
IsDelete = false,
CreatedDate = DateTime.Now,
Description = "test3"
});
var entity2 = CategoryRepository.Add(new CallStoreProc.Data.Entity.Category()
{
Name = "test4",
IsDelete = false,
CreatedDate = DateTime.Now,
Description = "test4"
});
uow.Save();
}
Part 1: Step up ADO.NET Entity Framework 4 CTP4
Part 3: Invoke store procedure in ADO.NET Entity Framework 4
{
/// <summary>
/// Gets all.
/// </summary>
/// <returns></returns>
IEnumerable<T> GetAll();
/// <summary>
/// Gets the specified where.
/// </summary>
/// <param name="where">The where.</param>
/// <returns></returns>
IEnumerable<T> Get(Func<T, bool> where);
}
I also have a base Repository for re-use all things that you think it can shared for all Repository used.
public abstract class BaseRepository<T> : IDisposable
{
private DbContext _dbContext;
/// <summary>
/// Initializes a new instance of the <see cref="BaseRepository<T>"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public BaseRepository(IDatabaseFactory databaseFactory)
{
Contract.Assert(databaseFactory != null, "DatabaseFactory is null");
DatabaseFactory = databaseFactory;
}
/// <summary>
/// Gets or sets the database factory.
/// </summary>
/// <value>The database factory.</value>
protected IDatabaseFactory DatabaseFactory
{
get;
private set;
}
/// <summary>
/// Gets the db context.
/// </summary>
/// <value>The db context.</value>
protected DbContext DbContext
{
[DebuggerStepThrough]
get
{
return _dbContext ?? (_dbContext = DatabaseFactory.Get());
}
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
if (DbContext != null)
GC.SuppressFinalize(DbContext);
if (DatabaseFactory != null)
GC.SuppressFinalize(DatabaseFactory);
}
}
Now we can implement the CategoryRepository as below:
public interface ICategoryRepository : ICommandRepository<Category>, IQueryRepository<Category>
{
}
public class CategoryRepository : BaseRepository<Category>, ICategoryRepository
{
/// <summary>
/// Initializes a new instance of the <see cref="CategoryRepository"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public CategoryRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
/// <summary>
/// Units the of work.
/// </summary>
/// <returns></returns>
public IUnitOfWork UnitOfWork()
{
return DbContext as CSPDbContext;
}
/// <summary>
/// Gets the by id.
/// </summary>
/// <param name="id">The id.</param>
/// <returns></returns>
public Category GetById(int id)
{
Contract.Assert(DbContext != null, "DbContext is null");
var temp = DbContext as CSPDbContext;
return (temp).Categories.Where<Category>(x => x.Id == id).FirstOrDefault<Category>();
}
/// <summary>
/// Adds the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
/// <returns></returns>
public Category Add(Category entity)
{
Contract.Assert(DbContext != null, "DbContext is null");
var temp = DbContext as CSPDbContext;
temp.Categories.Add(entity);
return entity;
}
...
}
Unit of Work on EF4
This is a hard pattern in EF4, so I will don’t explain about it. I just gave you a reference to read it, and I also implemented according to this link
http://blogs.msdn.com/b/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx
This is my code:
public interface IUnitOfWork
{
/// <summary>
/// Saves this instance.
/// </summary>
void Save();
}
public partial class CSPDbContext : DbContext, IUnitOfWork
{
...
/// <summary>
/// Saves this instance.
/// </summary>
public void Save()
{
SaveChanges();
}
}
I gave the CSPDbContext implementing the IUnitOfWork contract, and
public class CategoryRepository : BaseRepository<Category>, ICategoryRepository
{
/// <summary>
/// Initializes a new instance of the <see cref="CategoryRepository"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public CategoryRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
/// <summary>
/// Units the of work.
/// </summary>
/// <returns></returns>
public IUnitOfWork UnitOfWork()
{
return DbContext as CSPDbContext;
}
...
}
{
private DbContext _dbContext;
/// <summary>
/// Initializes a new instance of the <see cref="BaseRepository<T>"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public BaseRepository(IDatabaseFactory databaseFactory)
{
Contract.Assert(databaseFactory != null, "DatabaseFactory is null");
DatabaseFactory = databaseFactory;
}
/// <summary>
/// Gets or sets the database factory.
/// </summary>
/// <value>The database factory.</value>
protected IDatabaseFactory DatabaseFactory
{
get;
private set;
}
/// <summary>
/// Gets the db context.
/// </summary>
/// <value>The db context.</value>
protected DbContext DbContext
{
[DebuggerStepThrough]
get
{
return _dbContext ?? (_dbContext = DatabaseFactory.Get());
}
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
if (DbContext != null)
GC.SuppressFinalize(DbContext);
if (DatabaseFactory != null)
GC.SuppressFinalize(DatabaseFactory);
}
}
Now we can implement the CategoryRepository as below:
public interface ICategoryRepository : ICommandRepository<Category>, IQueryRepository<Category>
{
}
public class CategoryRepository : BaseRepository<Category>, ICategoryRepository
{
/// <summary>
/// Initializes a new instance of the <see cref="CategoryRepository"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public CategoryRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
/// <summary>
/// Units the of work.
/// </summary>
/// <returns></returns>
public IUnitOfWork UnitOfWork()
{
return DbContext as CSPDbContext;
}
/// <summary>
/// Gets the by id.
/// </summary>
/// <param name="id">The id.</param>
/// <returns></returns>
public Category GetById(int id)
{
Contract.Assert(DbContext != null, "DbContext is null");
var temp = DbContext as CSPDbContext;
return (temp).Categories.Where<Category>(x => x.Id == id).FirstOrDefault<Category>();
}
/// <summary>
/// Adds the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
/// <returns></returns>
public Category Add(Category entity)
{
Contract.Assert(DbContext != null, "DbContext is null");
var temp = DbContext as CSPDbContext;
temp.Categories.Add(entity);
return entity;
}
...
}
Unit of Work on EF4
This is a hard pattern in EF4, so I will don’t explain about it. I just gave you a reference to read it, and I also implemented according to this link
http://blogs.msdn.com/b/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx
This is my code:
public interface IUnitOfWork
{
/// <summary>
/// Saves this instance.
/// </summary>
void Save();
}
public partial class CSPDbContext : DbContext, IUnitOfWork
{
...
/// <summary>
/// Saves this instance.
/// </summary>
public void Save()
{
SaveChanges();
}
}
public interface IUnitOfWork
{
/// <summary>
/// Saves this instance.
/// </summary>
void Save();
}
public partial class CSPDbContext : DbContext, IUnitOfWork
{
...
/// <summary>
/// Saves this instance.
/// </summary>
public void Save()
{
SaveChanges();
}
}
I gave the CSPDbContext implementing the IUnitOfWork contract, and
public class CategoryRepository : BaseRepository<Category>, ICategoryRepository
{
/// <summary>
/// Initializes a new instance of the <see cref="CategoryRepository"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public CategoryRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
/// <summary>
/// Units the of work.
/// </summary>
/// <returns></returns>
public IUnitOfWork UnitOfWork()
{
return DbContext as CSPDbContext;
}
...
}
{
/// <summary>
/// Initializes a new instance of the <see cref="CategoryRepository"/> class.
/// </summary>
/// <param name="databaseFactory">The database factory.</param>
public CategoryRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
/// <summary>
/// Units the of work.
/// </summary>
/// <returns></returns>
public IUnitOfWork UnitOfWork()
{
return DbContext as CSPDbContext;
}
...
}
Now I do unit testing for CategoryRepository as:
[TestMethod()]
public void GetAllTesting()
{
var result = CategoryRepository.GetAll();
Assert.IsNotNull(result);
}[TestMethod()]
public void AddCategoryTesting()
{
var entity = CategoryRepository.Add(new CallStoreProc.Data.Entity.Category()
{
Name = "test",
IsDelete = false,
CreatedDate = DateTime.Now,
Description = "test"
});
Assert.IsNotNull(entity);
Assert.AreEqual(entity.Name, "test");
Assert.AreEqual(entity.IsDelete, false);
}Unit testing for UnitOfWork:
[TestMethod()]
public void UnitOfWorkTesting()
{
var uow = CategoryRepository.UnitOfWork();
var entity1 = CategoryRepository.Add(new CallStoreProc.Data.Entity.Category()
{
Name = "test3",
IsDelete = false,
CreatedDate = DateTime.Now,
Description = "test3"
});
var entity2 = CategoryRepository.Add(new CallStoreProc.Data.Entity.Category()
{
Name = "test4",
IsDelete = false,
CreatedDate = DateTime.Now,
Description = "test4"
});
uow.Save();
}
Part 1: Step up ADO.NET Entity Framework 4 CTP4
Part 3: Invoke store procedure in ADO.NET Entity Framework 4