加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 使用具有实体框架的UnitOfWork和存储库模式

发布时间:2020-12-16 00:23:02 所属栏目:百科 来源:网络整理
导读:我将在我的数据访问层中使用存储库和UnitOfwork来执行此操作,查看一个联系人aggregateroot public interface IAggregateRoot { } 这是我的Generic存储库接口: public interface IRepositoryT { IEnumerableT GetAll(); T FindBy(params Object[] keyValues)
我将在我的数据访问层中使用存储库和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和泛型方法)
因为我想将ContactRepository方法提供给一些特定的查询,
有人帮忙吗?

解决方法

它不是您问题的直接答案,但它可以简化一些事情并减少重复.

当你使用例如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也能开箱即用.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读