【问题标题】:C# with Entity Framework Is there a way to implement repository pattern with an abstract base class?带有实体框架的 C# 有没有办法使用抽象基类来实现存储库模式?
【发布时间】:2013-03-16 02:43:43
【问题描述】:

我希望我的存储库继承自抽象类(基础存储库),而不是接口。我决定要使用抽象类,因为我不会对存储库进行单元测试(我将改为对服务层进行单元测试)并且我不想将相同的实现复制到从该基础存储库继承的每个存储库类.

例如:

public abstract class BaseRepository<T> where T : class
{
    protected DbSet<T> dbSet;

    public BaseRepository(DbContext dataContext)
    {
        dbSet = dataContext.Set<T>();
    }

    public void Insert(T entity)
    {
        dbSet.Add(entity);
    }

    public IEnumerable<T> SearchFor(Expression<Func<T, bool>> predicate)
    {
        return dbSet.Where(predicate);
    }

    public IEnumerable<T> GetAll()
    {
        return dbSet;
    }

    public T GetById(int id)
    {
        return dbSet.Find(id);
    }
}

当我尝试创建从该基础存储库继承的其他存储库时,构造函数出现问题。如何将数据上下文传递到这些派生类中以便它们可以使用?

【问题讨论】:

    标签: c# entity-framework repository-pattern


    【解决方案1】:

    你需要在构造函数中传递上下文:

        public class Repository<TEntity> where TEntity : class
        {
            internal MyEntities context;
            internal DbSet<TEntity> dbSet;
    
            public Repository(MyEntities context)
            {
                this.context = context;
                this.dbSet = context.Set<TEntity>();
            }
    
            public virtual IEnumerable<TEntity> Get(
                Expression<Func<TEntity, bool>> filter = null,
                Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
                string includeProperties = "")
            {
                IQueryable<TEntity> query = dbSet;
    
                if (filter != null)
                {
                    query = query.Where(filter);
                }
    
                foreach (var includeProperty in includeProperties.Split
                    (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    query = query.Include(includeProperty);
                }
    
                if (orderBy != null)
                {
                    return orderBy(query).ToList();
                }
                else
                {
                    return query.ToList();
                }
            }
    
            public virtual TEntity GetByID(object id)
            {
                return dbSet.Find(id);
            }
    
            public virtual void Insert(TEntity entity)
            {
                dbSet.Add(entity);
            }
    
            public virtual void Delete(object id)
            {
                TEntity entityToDelete = dbSet.Find(id);
                Delete(entityToDelete);
            }
    
            public virtual void Delete(TEntity entityToDelete)
            {
                if (context.Entry(entityToDelete).State == EntityState.Detached)
                {
                    dbSet.Attach(entityToDelete);
                }
                dbSet.Remove(entityToDelete);
            }
    
            public virtual void Update(TEntity entityToUpdate)
            {
                dbSet.Attach(entityToUpdate);
                context.Entry(entityToUpdate).State = EntityState.Modified;
            }
        }
    

    用途:

    var repo = new Repository<MyClass>(context);
    

    【讨论】:

    • 您的示例将不起作用,因为我的基类是抽象的。在 C# 中,抽象类不能被实例化。
    • 不要让它成为抽象基类。在你的 UnitOfWork 类中创建你的 repo,并用这个 Repo 类实例化它们。
    • 我想创建一个抽象基类,这样我就不必向所有存储库类添加相同的实现。我看不到创建接口的意义,因为我只会使用假服务类对控制器进行单元测试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    • 1970-01-01
    • 2016-09-02
    • 2015-07-15
    • 2012-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多