【问题标题】:Interface problems with repository design pattern in C# MVC4 and EF5C# MVC4 和 EF5 中存储库设计模式的接口问题
【发布时间】:2014-10-11 16:53:46
【问题描述】:

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

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

我将他教程中的代码更改为不使用 Async 如下(他的原始代码在 cmets 中):

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);
}

这里是接口完成一些基本实现后生成的代码(repository):

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
}

他的教程内容再次出现在 cmets 中。经过一些迭代后,我最终达到了上述要求,但现在当我尝试使用最后 3 种方法时遇到了问题。这是 2 种工作 GetAll 和 GetById 的方法。它们出现在智能感知中,但插入没有。

    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);
    }

我假设(可能是错误的)所说的方法默认是私有的,这就是为什么当我像他在控制器上推荐的那样使用它们时它们没有出现(其他出现在智能感知中,但最后三个甚至没有出现建筑)。

所以我第一次教,让他们公开权利...我确实在他们面前放了公共访问修饰符,但后来我得到了这个错误:

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

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

提前致谢。

【问题讨论】:

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


【解决方案1】:

您似乎已经明确实现了您说不起作用的接口方法:

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

试试:

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

相反

【讨论】:

  • 感谢您的回答。我想补充一点,我只需单击实现接口选项即可自动完成整个操作。那为什么会这样呢?
  • 例如,当您实现两个具有相同签名的方法的接口时,您将显式实现。 This 回答很好地突出了一个用例
【解决方案2】:

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

【讨论】:

  • 问题一:不能在接口中声明public/private。问题 2:当我在生成的类中将它们声明为 public 时,我得到了问题末尾描述的错误。因此问题。感谢您花时间回答,但它没有回答提出的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-21
  • 1970-01-01
相关资源
最近更新 更多