C#MVC4和EF5中存储库设计模式的接口问题

时间:2014-10-11 16:53:46

标签: c# asp.net-mvc-4 repository-pattern

我正在使用MVC关注存储库设计模式上的一个简单的YouTube教程(链接here)。它很好,但他使用的MVC5和EF6对Async方法有很多支持。

我正在使用MVC4并且在我尝试升级项目以使用EF6时遇到了重大问题。所以我只使用EF5,但这不是问题。

我修改了他的教程中的代码,不按如下方式使用Async(他的原始代码在注释中):

public interface IGenericRepo<TEntity>
{
    IQueryable<TEntity> GetAll();

    //Task<TEntity> GetByIdAsync(int id);
    TEntity GetById(int id);

    IQueryable<TEntity> SearchFor(Expression<Func<TEntity, bool>> predicate);

    //Task EditAsync(TEntity entity);
    void Edit(TEntity entity);

    //Task InsertAsync(TEntity entity);
    void Insert(TEntity entity);

    //Task DeleteAsync(TEntity entity);
    void Delete(TEntity entity);
}

以下是完成一些基本实现后接口生成的代码(存储库):

public class GenericRepo<TEntity> : IGenericRepo<TEntity> where TEntity : class
{
    protected DbSet<TEntity> DbSet;
    private readonly DbContext dbContext;

    public GenericRepo() { }

    public GenericRepo(DbContext dbContext)
    {
        this.dbContext = dbContext;
        DbSet = dbContext.Set<TEntity>();
    }

    public IQueryable<TEntity> GetAll()
    {
        return DbSet;
    }

    //public async Task<TEntity> GetByIdAsync(int id)
    public TEntity GetById(int id)
    {
        //return await DbSet.FindAsync(id);
        return DbSet.Find(id);
    }

    public IQueryable<TEntity> SearchFor(Expression<Func<TEntity, bool>> predicate)
    {
        return DbSet.Where(predicate);
    }

    //public async Task EditAsync(TEntity entity)
    public void IGenericRepo<TEntity>.Edit(TEntity entity)
    {
        dbContext.Entry(entity).State = EntityState.Modified;
        //await dbContext.SaveChangesAsync();
        dbContext.SaveChanges();
    }

    //public async Task InsertAsync(TEntity entity)
    void IGenericRepo<TEntity>.Insert(TEntity entity)
    {
        DbSet.Add(entity);
        //await dbContext.SaveChangesAsync();
        dbContext.SaveChanges();
    }

    //public async Task DeleteAsync(TEntity entity)
    void IGenericRepo<TEntity>.Delete(TEntity entity)
    {
        DbSet.Remove(entity);
        //await dbContext.SaveChangesAsync();
        dbContext.SaveChanges();
    }
    #endregion
}

他的教程再次在评论中。经过一些迭代后,我最终得到了上面的内容,但是当我尝试使用最后3种方法时,我遇到了问题。以下是使用GetAll和GetById的两种方法。它们出现在intellisense中,但插入的却没有。

    GenericRepo<Course> repo = new GenericRepo<Course>(new SchoolDemoEntity());

    // GET: /Course/
    public ActionResult Index()
    {
        return View(repo.GetAll()); //This works
    }

    // GET: /Course/Details/5
    public ActionResult Details(int id = 0)
    {
        Course course = repo.GetById(id); //This works

        if (course == null) return HttpNotFound();

        return View(course);
    }

    // POST: /Course/Create
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(Course course)
    {
        if (ModelState.IsValid)
        {
            repo.Insert(course); //This fails to show in intellisense and obviously I get a red underline.
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(course);
    }

我假设(可能是错误的)默认情况下这些方法是私有的,这就是为什么当我按照他在控制器上推荐使用它们时它们不出现的原因(其他人出现在intellisense中但最后三个甚至没有出现在建筑)。

所以我的第一次教学,让他们公开对...我确实把公共访问修饰符放在他们面前但是我得到了这个错误:

"The modifier 'public' is not valid for this item"

如果我不添加公开,我无法使用它,但如果我这样做,我会收到错误。我显然不能将它添加到界面中,所以我真的想知道如何解决这个问题。

提前致谢。

2 个答案:

答案 0 :(得分:3)

看起来你已经明确地实现了你说不起作用的接口方法:

void IGenericRepo<TEntity>.Insert(TEntity entity){...}

尝试:

public void Insert(TEntity entity) {...}

相反

答案 1 :(得分:0)

最后两种方法不是公共方法。将它们声明为可以访问的公共方法。