我应该使用实体框架5的通用存储库吗

本文关键字:存储 实体 框架 我应该 | 更新日期: 2023-09-27 18:22:51

我目前正在使用具有通用存储库和工作单元模式的实体框架。我的模型与本文中描述的模型相似

我过去使用过通用存储库,非常喜欢它所能提供的全局功能。然而,当我将它与实体框架一起使用时,我似乎每天都会遇到更多的问题。当涉及到处理父母/子女/交叉关系时,这些问题似乎会出现得更多。

将Generic Repository与EF一起使用开始给我留下不好的印象,我开始认为将Generice Repository与EF一起使用是错误的方法。

有人能帮我指引正确的方向吗?

我应该使用实体框架5的通用存储库吗

这篇文章的方法真的很痛苦,因为在EF中已经有了一个通用存储库和一个通用IUnitOfWork,为每种类型创建特定的存储库只会消除通用的好处!

我在这里发布了一个关于我如何拥有通用存储库和IUnitOfWork的示例,有了它,你就可以拥有一个非常好的存储库!

public interface IUnitOfWork : IDisposable
{
    void Save();
    void Save(SaveOptions saveOptions);
}
public interface IRepository<TEntity> : IDisposable where TEntity : class
{
    IUnitOfWork Session { get; }
    IList<TEntity> GetAll();
    IList<TEntity> GetAll(Expression<Func<TEntity, bool>> predicate);
    bool Add(TEntity entity);
    bool Delete(TEntity entity);
    bool Update(TEntity entity);
    bool IsValid(TEntity entity);
}

实现方式类似于:

public class Repository : Component, IRepository
{
    protected DbContext session;
    public virtual IUnitOfWork Session
    {
        get
        {
            if (session == null)
                throw new InvalidOperationException("A session IUnitOfWork do repositório não está instanciada.");
            return (session as IUnitOfWork);
        }
    }
    public virtual DbContext Context
    {
        get
        {
            return session;
        }
    }
    public Repository(IUnitOfWork instance)
    {
        SetSession(instance);
    }
    public IList<TEntity> GetAll<TEntity>() where TEntity : class
    {
        return session.Set<TEntity>().ToList();
    }
    public IList<TEntity> GetAll<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
    {
        return session.Set<TEntity>().Where(predicate).ToList();
    }
    public bool Add<TEntity>(TEntity entity) where TEntity : class
    {
        if (!IsValid(entity))
            return false;
        try
        {
            session.Set(typeof(TEntity)).Add(entity);
            return session.Entry(entity).GetValidationResult().IsValid;
        }
        catch (Exception ex)
        {
            if (ex.InnerException != null)
                throw new Exception(ex.InnerException.Message, ex);
            throw new Exception(ex.Message, ex);
        }
    }
    public bool Delete<TEntity>(TEntity entity) where TEntity : class
    {
        if (!IsValid(entity))
            return false;
        try
        {
            session.Set(typeof(TEntity)).Remove(entity);
            return session.Entry(entity).GetValidationResult().IsValid;
        }
        catch (Exception ex)
        {
            if (ex.InnerException != null)
                throw new Exception(ex.InnerException.Message, ex);
            throw new Exception(ex.Message, ex);
        }
    }
    public bool Update<TEntity>(TEntity entity) where TEntity : class
    {
        if (!IsValid(entity))
            return false;
        try
        {
            session.Set(typeof(TEntity)).Attach(entity);
            session.Entry(entity).State = EntityState.Modified;
            return session.Entry(entity).GetValidationResult().IsValid;
        }
        catch (Exception ex)
        {
            if (ex.InnerException != null)
                throw new Exception(ex.InnerException.Message, ex);
            throw new Exception(ex.Message, ex);
        }
    }
    public virtual bool IsValid<TEntity>(TEntity value) where TEntity : class
    {
        if (value == null)
            throw new ArgumentNullException("A entidade não pode ser nula.");
        return true;
    }
    public void SetSession(IUnitOfWork session)
    {
        SetUnitOfWork(session);
    }
    protected internal void SetUnitOfWork(IUnitOfWork session)
    {
        if (!(session is DbContext))
            throw new ArgumentException("A instância IUnitOfWork deve um DbContext.");
        SetDbContext(session as DbContext);
    }
    protected internal void SetDbContext(DbContext session)
    {
        if (session == null)
            throw new ArgumentNullException("DbContext: instance");
        if (!(session is IUnitOfWork))
            throw new ArgumentException("A instância DbContext deve implementar a interface IUnitOfWork.");
        this.session = session;
    }
}