我正在玩最新的Entity Framework CTP 5版本,并建立一个简单的asp.net MVC博客,其中我只有两个表:发布和评论。这完全在POCO完成,我只需要帮助DbContext部分,我需要它是单元测试(使用IDbSet?)和我需要一个简单/通用存储库模式的添加,更新,删除,检索。任何帮助是赞赏。
谢谢。
解决方法
从你开始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();
- }
您将需要使用IoC容器,如StructureMap,使这项工作。你可以通过NuGet安装结构图,或者如果你使用MVC 3,你可以安装StructureMap-MVC NuGet包。 (下面链接)
Install-Package StructureMap.MVC4
Install-Package StructureMap.MVC3
如果你有问题,只是让我知道。希望它有帮助。