实体框架4 CTP 4 / CTP 5通用存储库模式和单元可测试我正在玩最新的Entity Framework CTP 5版本并构建一个简单的asp.net MVC博客,其中我只有两个表:Post和Comments。这完全是在POCO中完成的,我只需要DbContext部分的帮助,我需要它可以进行单元测试(使用IDbSet?),我需要一个简单/通用的存储库模式来添加,更新,删除,检索。任何帮助表示赞赏。
3 回答
冉冉说
TA贡献1877条经验 获得超1个赞
从DbContext开始,创建一个名为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(); }}
定义IDatabaseFactory并使用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.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() { } }
现在我们可以定义我们的IRepository和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(); } }
现在您可以创建IPostRepository和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); } }
最后,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();}
在您的控制器中使用:
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包。(以下链接)
Install-Package StructureMap.MVC3
如果您有任何疑问,请告诉我。希望能帮助到你。
- 3 回答
- 0 关注
- 421 浏览
添加回答
举报
0/150
提交
取消