实体框架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 关注
- 479 浏览
添加回答
举报
0/150
提交
取消
