Должен ли я использовать общий репозиторий с платформой Entity Framework 5?

В настоящее время я использую Entity Framework с универсальным репозиторием и модулем работы. Моя модель аналогична описанной в этой статье

Я использовал Generic Repositories в прошлом и действительно наслаждался глобальной функциональностью, которую он может предоставить. Однако кажется, что я сталкиваюсь с большими проблемами каждый день, когда дело доходит до использования его с Entity Framework. Эти проблемы, похоже, возникают еще больше, когда дело касается отношений с родителями/детьми/связями.

Использование Generic Repository с EF начинает оставлять плохой вкус во рту, и я начинаю думать, что использование универсального репозитория с EF является неправильным подходом.

Может ли кто-нибудь помочь мне направить меня в правильном направлении?

Ответы

Ответ 1

Подход к этой статье - это действительно то, что может стать болью, потому что у вас уже есть общий репозиторий и общий IUnitOfWork в EF, а создание конкретного репозитория для каждого типа просто удаляет выгоду от общего!

Я размещаю здесь пример того, как у меня есть общий репозиторий и мой 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;
    }

}