当前位置: 首页 > 知识库问答 >
问题:

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

孔光赫
2023-03-14

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

我正在使用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
}

同样,他的辅导材料在评论中。经过一些迭代之后,我最终达到了上面的方法,但是现在当我试图使用最后三种方法时,我遇到了一个问题。下面是GetAll和GetById的两个工作方法。它们出现在intellisense中,但Insert one没有。

    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,我就不能使用它,但如果添加了,我会收到一个错误。我显然无法将此添加到界面,所以我很想知道如何修复此问题。

提前感谢。

共有2个答案

孙成益
2023-03-14

最后两个方法不是公共方法。将它们声明为公共方法,然后可以访问这些方法。

章鸿光
2023-03-14

看起来您已经明确实现了您认为不起作用的接口方法:

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

尝试:

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

代替

 类似资料:
  • 前言:我试图在关系数据库的MVC体系结构中使用存储库模式。 我最近开始学习PHP中的TDD,我意识到我的数据库与应用程序的其余部分耦合得太紧密了。我读过关于存储库和使用IoC容器将其“注入”到我的控制器中的文章。很酷的东西。但现在有一些关于存储库设计的实际问题。请考虑以下示例。 所有这些查找方法都使用选择所有字段()方法。然而,在我的应用程序中,我总是试图限制我得到的字段的数量,因为这经常增加开销

  • 问题内容: 前言:我正在尝试在MVC体系结构和关系数据库中使用存储库模式。 我最近开始学习PHP中的TDD,并且意识到我的数据库与我的其余应用程序之间的联系太紧密了。我已经阅读了有关存储库并使用IoC容器将其“注入”到控制器中的信息。很酷的东西。但是现在有一些关于存储库设计的实际问题。考虑以下示例。 问题1:字段过多 所有这些查找方法均使用全选()方法。但是,在我的应用程序中,我总是试图限制获得的

  • 我查阅了许多存储库设计模式教程,如 https://asperbrothers.com/blog/implement-repository-pattern-in-laravel/ https://www.larashout.com/how-to-use-repository-pattern-in-laravel https://laravelarticle.com/repository-desig

  • 本文向大家介绍C++设计模式之桥接模式(Bridge),包括了C++设计模式之桥接模式(Bridge)的使用技巧和注意事项,需要的朋友参考一下 桥接模式属于先天模式,这里的先天模式就是说一开始就要把结构搭建好,方便后来的扩展,而不是对已经出现的模块和接口进行改进扩展的。桥接的核心在于实体类和操作类之间的聚合关系,这个聚合关系就是我们所说的"桥",不同于装饰、代理和适配器模式的中的聚合关系,桥接不存

  • 关于存储库模式,我有几个问题: > 如果我只使用离线数据库(例如Room with LiveData),是否使用存储库模式? 如果我的应用程序现在离线,但将来会连接到远程数据库,那么我应该实现存储库模式还是以后再做就不会有问题了?

  • 问题内容: 最近,我碰到了C ++的Singleton设计模式的实现/实现。它看起来像这样(我从现实生活的示例中采用了它): 从该声明中,我可以推断出实例字段是在堆上初始化的。这意味着存在内存分配。对我来说,完全不清楚的是何时确切地将要释放内存?还是有错误和内存泄漏?似乎实现中存在问题。 我的主要问题是,如何以正确的方式实施它? 问题答案: 在2008年,我提供了Singleton设计模式的C +