c# – 使用具有实体框架的UnitOfWork和存储库模式
我将在我的数据访问层中使用存储库和UnitOfwork来执行此操作,查看一个联系人aggregateroot
public interface IAggregateRoot { } 这是我的Generic存储库接口: public interface IRepository<T> { IEnumerable<T> GetAll(); T FindBy(params Object[] keyValues); void Add(T entity); void Update(T entity); void Delete(T entity); } 和我在模型中的POCO Contact类 public class Contact :IAggregateRoot { public Guid Id { get; set; } public string Name { get; set; } public string Email { get; set; } public string Title { get; set; } public string Body { get; set; } public DateTime CreationTime { get; set; } } 这是我继承自IRepository的IContactRepository,也可能是自己的方法 public interface IContactRepository : IRepository<Contact> { } 现在我已经完成了IUitOfWork和UnitOfwork public interface IUnitOfWork { IRepository<Contact> ContactRepository { get; } } public class UnitOfWork : IUnitOfWork { private readonly StatosContext _statosContext = new StatosContext(); private IRepository<Contact> _contactUsRepository; public IRepository<Contact> ContactRepository { get { return _contactUsRepository ?? (_contactUsRepository = new Repository<Contact>(_statosContext)); } } } 关于我的存储库 public class Repository<T> : IRepository<T> where T : class,IAggregateRoot { //implementing methods } 我可以通过Service中的UnitOfwork访问存储库来执行所有CRUD操作,例如: _unitOfWork.ContactRepository.Add(contact); _unitOfWork.SaveChanges(); 但我想这样做 _ ContactRepository.Add(contact); _unitOfWork.SaveChanges(); (通过_unitOfWork.ContactRepository通过_ContactRepository No获取CRUD和泛型方法) 解决方法
它不是您问题的直接答案,但它可以简化一些事情并减少重复.
当你使用例如EntityFramework Power Tools对Code First进行逆向工程(或者一般只使用Code First),最终得到的DbContext类充当UoW和存储库,例如: public partial class YourDbContext : DbContext { public DbSet<Contact> Contacts {get; set;} } 现在,如果你想让事情变得可测试,那么有一个简单的方法:引入一个非常精简的界面: public interface IDbContext { IDbSet<T> EntitySet<T>() where T : class; int SaveChanges(); //you can reveal more methods from the original DbContext,like `GetValidationErrors` method or whatever you really need. } 然后使用分部类的第二部分创建另一个文件: public partial class YourDbContext : IDbContext { public IDbSet<T> EntitySet<T>() where T : class { return Set<T>(); } } 当当!现在您可以使用YourDbContext注入IDbContext: //context is an injected IDbContext: var contact = context.EntitySet<Contact>().Single(x => x.Id == 2); contact.Name = "Updated name"; context.EntitySet<Contact>().Add(new Contact { Name = "Brand new" }); context.SaveChanges(); 现在,如果您想控制上下文的处理,那么您必须编写自己的(喘气)IDbContextFactory(通用与否,根据您的需要)并注入该工厂. 现在不需要编写自己的查找,添加或更新方法,DbContext将适当地处理它,更容易引入显式事务,并且一切都很好地隐藏在接口后面(IDbContext,IDbSet). 顺便说一句,IDbContextFactory将等同于NHibernate的ISessionFactory和IDbContext – ISession.我希望EF也能开箱即用. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |