实体框架4 CTP 4 / CTP 5通用存储库模式和单元可测试 [英] Entity Framework 4 CTP 4 / CTP 5 Generic Repository Pattern and Unit Testable
问题描述
从你开始DbContext,创建一个名为Database.cs的新文件:
Database.cs
public class数据库:DbContext
{
private IDbSet< Post> _posts;
public IDbSet< Post>帖子{
get {return _posts ?? (_posts = DbSet< Post>()); }
}
public virtual IDbSet< T> DbSet< T>()其中T:class {
return Set< T>();
}
public virtual void Commit(){
base.SaveChanges();
}
}
定义一个IDatabaseFactory并使用DatabaseFactory实现: p>
IDatabaseFactory.cs
public interface IDatabaseFactory :IDisposable
{
数据库Get();
}
DatabaseFactory.cs
public class DatabaseFactory:Disposable,IDatabaseFactory {
private Database _database;
public Database Get(){
return _database ?? (_database = new Database());
}
protected override void DisposeCore(){
if(_database!= null)
_database.Dispose();
}
}
一次性扩展方法:
Disposable.cs
public class Disposable:IDisposable
{
private bool isDisposed;
〜Disposable()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposal)
{
if(!isDisposed&&&& amp;))
{
DisposeCore();
}
isDisposed = true;
}
protected virtual void DisposeCore()
{
}
}
现在我们可以定义我们的IRepository和我们的RepositoryBase
IRepository.cs
public interface IRepository< T>其中T:class
{
void Add(T entity);
void Delete(T entity);
void Update(T entity);
T GetById(long Id);
IEnumerable< T>所有();
IEnumerable< T> AllReadOnly();
}
RepositoryBase.cs
public abstract class RepositoryBase< T>其中T:class
{
private Database _database;
private readonly IDbSet< T> _dbset;
protected RepositoryBase(IDatabaseFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
_dbset = Database.Set< T>();
}
protected IDatabaseFactory DatabaseFactory
{
get;私人集合
}
protected数据库数据库
{
get {return _database ?? (_database = DatabaseFactory.Get());
}
public virtual void Add(T entity)
{
_dbset.Add(entity);
}
public virtual void Delete(T entity)
{
_dbset.Remove(entity);
}
public virtual void Update(T entity)
{
_database.Entry(entity).State = EntityState.Modified;
}
public virtual T GetById(long id)
{
return _dbset.Find(id);
}
public virtual IEnumerable< T> All()
{
return _dbset.ToList();
}
public virtual IEnumerable< T> AllReadOnly()
{
return _dbset.AsNoTracking()。ToList();
}
}
现在您可以创建您的IPostRepository和PostRepository: p>
IPostRepository.cs
public interface IPostRepository :IRepository< Post>
{
//如果需要,可以在此添加自定义方法
发布ByTitle(string title);
}
PostRepository.cs
public class PostRepository:RepositoryBase< Post>,IPostRepository
{
public PostRepository(IDatabaseFactory databaseFactory):base(databaseFactory)
{
}
public Post ByTitle(string title){
return base.Database.Posts.Single(x => x.Title == title);
}
}
最后,UoW:
IUnitOfWork.cs
public interface IUnitOfWork
{
void Commit();
}
UnitOfWork.cs
private readonly IDatabaseFactory _databaseFactory;
私人数据库_database;
public UnitOfWork(IDatabaseFactory databaseFactory)
{
_databaseFactory = databaseFactory;
}
protected数据库数据库
{
get {return _database ?? (_database = _databaseFactory.Get()); }
}
public void Commit()
{
Database.Commit();
}
在控制器中使用
private readonly IPostRepository _postRepository;
private readonly IUnitOfWork_unitOfWork;
public PostController(IPostRepository postRepository,IUnitOfWork unitOfWork)
{
_postRepository = postRepository;
_unitOfWork = unitOfWork;
}
public ActionResult Add(Post post){
_postRepository.Add(post);
_unitOfWork.Commit();
}
您将需要使用像StructureMap这样的IoC容器才能使其工作。您可以通过NuGet安装结构图,或者如果使用MVC 3,则可以安装StructureMap-MVC NuGet软件包。 (链接)
安装 - Package StructureMap.MVC3
如果您有任何疑问,请告诉我们。希望有帮助。
I'm playing with the latest Entity Framework CTP 5 release and building a simple asp.net MVC blog where I just have two tables: Post and Comments. This is done entirely in POCO, I just need help on the DbContext part, where I need it to be unit testable (using IDbSet?) and I need a simple/generic repository pattern for add, update, delete, retrieval. Any help is appreciated.
Thanks.
Start with you DbContext, create a new file called Database.cs:
Database.cs
public class Database : DbContext
{
private IDbSet<Post> _posts;
public IDbSet<Post> Posts {
get { return _posts ?? (_posts = DbSet<Post>()); }
}
public virtual IDbSet<T> DbSet<T>() where T : class {
return Set<T>();
}
public virtual void Commit() {
base.SaveChanges();
}
}
Define a IDatabaseFactory and implement it with DatabaseFactory:
IDatabaseFactory.cs
public interface IDatabaseFactory : IDisposable
{
Database Get();
}
DatabaseFactory.cs
public class DatabaseFactory : Disposable, IDatabaseFactory {
private Database _database;
public Database Get() {
return _database ?? (_database = new Database());
}
protected override void DisposeCore() {
if (_database != null)
_database.Dispose();
}
}
Disposable extension method:
Disposable.cs
public class Disposable : IDisposable
{
private bool isDisposed;
~Disposable()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if(!isDisposed && disposing)
{
DisposeCore();
}
isDisposed = true;
}
protected virtual void DisposeCore()
{
}
}
Now we can define our IRepository and our RepositoryBase
IRepository.cs
public interface IRepository<T> where T : class
{
void Add(T entity);
void Delete(T entity);
void Update(T entity);
T GetById(long Id);
IEnumerable<T> All();
IEnumerable<T> AllReadOnly();
}
RepositoryBase.cs
public abstract class RepositoryBase<T> where T : class
{
private Database _database;
private readonly IDbSet<T> _dbset;
protected RepositoryBase(IDatabaseFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
_dbset = Database.Set<T>();
}
protected IDatabaseFactory DatabaseFactory
{
get; private set;
}
protected Database Database
{
get { return _database ?? (_database = DatabaseFactory.Get()); }
}
public virtual void Add(T entity)
{
_dbset.Add(entity);
}
public virtual void Delete(T entity)
{
_dbset.Remove(entity);
}
public virtual void Update(T entity)
{
_database.Entry(entity).State = EntityState.Modified;
}
public virtual T GetById(long id)
{
return _dbset.Find(id);
}
public virtual IEnumerable<T> All()
{
return _dbset.ToList();
}
public virtual IEnumerable<T> AllReadOnly()
{
return _dbset.AsNoTracking().ToList();
}
}
Now you can create your IPostRepository and PostRepository:
IPostRepository.cs
public interface IPostRepository : IRepository<Post>
{
//Add custom methods here if needed
Post ByTitle(string title);
}
PostRepository.cs
public class PostRepository : RepositoryBase<Post>, IPostRepository
{
public PostRepository(IDatabaseFactory databaseFactory) : base(databaseFactory)
{
}
public Post ByTitle(string title) {
return base.Database.Posts.Single(x => x.Title == title);
}
}
Lastly, the UoW:
IUnitOfWork.cs
public interface IUnitOfWork
{
void Commit();
}
UnitOfWork.cs
private readonly IDatabaseFactory _databaseFactory;
private Database _database;
public UnitOfWork(IDatabaseFactory databaseFactory)
{
_databaseFactory = databaseFactory;
}
protected Database Database
{
get { return _database ?? (_database = _databaseFactory.Get()); }
}
public void Commit()
{
Database.Commit();
}
Using in your controller:
private readonly IPostRepository _postRepository;
private readonly IUnitOfWork_unitOfWork;
public PostController(IPostRepository postRepository, IUnitOfWork unitOfWork)
{
_postRepository = postRepository;
_unitOfWork = unitOfWork;
}
public ActionResult Add(Post post) {
_postRepository.Add(post);
_unitOfWork.Commit();
}
You will need to use an IoC container like StructureMap to make this work. You can install structure map via NuGet, or if you are using MVC 3, you can install the StructureMap-MVC NuGet package. (Links Below)
Install-Package StructureMap.MVC4
Install-Package StructureMap.MVC3
If you have questions just let me know. Hope it helps.
这篇关于实体框架4 CTP 4 / CTP 5通用存储库模式和单元可测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!