Repository Pattern with Entity Framework 4.1 and Code First
2013-01-06 16:25
555 查看
Introduction
A popular pattern for ORM data access is the Repository pattern. Repositories are currently very popular even in EF for the reasons below:Hide EF from upper layer
Make code better testable
The big disadvantage of EF is rigid architecture which can be hardly mocked, so if you want to unit test upper layer you must wrap EF somehow to allow mocking its implementation.
The solution I'll show is a very simple implementation of this pattern using EF 4.1 and code first to generate the database.
Using the code
We will start using a classic implementation of the Repository Pattern. In this section, I'll show a very generic one, but you can of course refactor it to be better suitable for your needs.Below the Repository Interface
Collapse | Copy Code
public interface IRepository<TEntity> : IDisposable where TEntity : IEntity { IQueryable<TEntity> GetAll(); void Delete(TEntity entity); void Add(TEntity entity); }
As you can see, we got a generic
GetAll()method which returns an
IQuerablethat allows to retrieve and query any entity in our model. Because the Repository uses generics, we have to constrain it(as you can see, this is a
TEntity).
Collapse | Copy Code
public interface IEntity { int Id { get; set; } }
Now let's see how to implement the repository pattern.
Collapse | Copy Code
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class, IEntity { private IDbContext_context; public Repository(IDbContextcontext) { _context = context; } private IDbSet<TEntity> DbSet { get { return _context.Set<TEntity>(); } } public IQueryable<TEntity> GetAll() { return DbSet.AsQueryable(); } public void Delete(TEntity entity) { DbSet.Remove(entity); } public void Add(TEntity entity) { DbSet.Add(entity); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposing) { if (_context != null) { _context.Dispose(); _context = null; } } } }
The repository has a constructor that takes an
IDbContextobject. That interface adds an abstraction layer on the EF
DbContextas shown below:
Collapse | Copy Code
public interface IDbContext{
IDbSet<TEntity> Set<TEntity>() where TEntity : class;
int SaveChanges();
void Dispose();
}
As you can see, the
IDbContexthas an
IDbSetproperty. This property represents an entity set that is used to perform create, read, update, and delete operations.
In EF, when you are using code first you need to create a Context which will contain all the
DbSetproperties that are used to access the entities in your model. The context class must inherit from
System.Data.EntityDbContextwhich provides facilities for querying and working with entity data as objects.
Below is the implementation of
DbContextwhich implements the above interface and Inherits from
DbContext.
Collapse | Copy Code
public class ApplicationContext : DbContext, IDbContext { public DbSet<User> User { get; set; } public new IDbSet<TEntity> Set<TEntity>() where TEntity : class { return base.Set<TEntity>(); } }
The
DbContextwill contain all the properties to access the entity in our context. In this example, it will access only "User". In this example, we use code first also to generate the DataBase: (only the entity that has got a relative DbSetwill be generated)
At this point, all we need to implement the repository pattern is done. At this point, we probably need to create the DataBase using code first approach.
For this scope, I have created another interface that will contain the DataBase initialization strategy.
Collapse | Copy Code
public interface IDatabaseInitializer<in TContext> where TContext : IDbContext { // Summary: // Executes the strategy to initialize // the database for the given context. // Parameters: // context: The context. void InitializeDatabase(TContext context); }
This interface is used to create the DataBase and allow the user to specify a kind of strategy. Let's assume we want to delete and create the DataBase every time we only need to implement the interface to specify what we need to do within the
InitializeDatabasemethod as shown below:
Collapse | Copy Code
public class DataBaseInitializer : IDatabaseInitializer<ApplicationContext> { public void InitializeDatabase(ApplicationContext context) { context.Database.Delete(); context.Database.Create(); } }
Now we got all we need.
First we need to initialize the DataBase (you need to add a connection string in your configuration file) as below:
Collapse | Copy Code
<connectionStrings> <add name="PeluSoft.ApplicationContext" providerName="System.Data.SqlClient" connectionString="Server=myServer;Database=TestUser;Persist Security Info=True;"/> </connectionStrings>
At this point, we are ready to initialize the DataBase:
Collapse | Copy Code
var context=new ApplicationContext(); var testDataBaseInitializer = new TestDataBaseInitializer(); testDataBaseInitializer.InitializeDatabase(context);
Then you can use the repository for the common operation on the entities.
Collapse | Copy Code
var context=new ApplicationContext(); var userRepo=new Repository<User>(context); var user =new User() { Username = "TestName" }; userRepo.Add(user); context.SaveChanges();
相关文章推荐
- Generic repository pattern and Unit of work with Entity framework
- SQLITE WITH ENTITY FRAMEWORK CODE FIRST AND MIGRATION
- Using the Repository Pattern with ASP.NET MVC and Entity Framework
- [转]Using the Repository Pattern with ASP.NET MVC and Entity Framework
- Code First/Entity Framework 4.1 Videos and Articles on MSDN
- How to execute a Stored Procedure with Entity Framework Code First
- [C#开发] SQLite with Entity Framework Code First
- Using Repository and Unit of Work patterns with Entity Framework 4.0
- Entity Framework With Mysql 之Code First
- Getting Started with Entity Framework 6 Code First using MVC 5--Contoso 大学
- Implementing Repository Pattern With Entity Framework
- Code-First Development with Entity Framework 4
- Code-First Development with Entity Framework 4
- Revisiting the Repository and Unit of Work Patterns with Entity Framework
- Entity Framework Code First - Stop autoincrement and use my Primary Key
- Using Repository and Unit of Work patterns with Entity Framework 4.0
- Entity Framework Code First属性映射约定
- Entity Framework CodeFirst------使用CodeFirst方式建立数据库连接(一)
- entity framework code first migrations
- 使用Entity Framework CodeFirst模式创建新数据库