繁体   English   中英

MVC EF数据库存储库模式

[英]MVC EF database repository pattern

我已经阅读了有关该主题的各种文章,但找不到我的问题的答案。

普遍的共识是,我应该为1个工作单元(例如1个网页)创建一个上下文。 因此,在我的Database.cs(参见下文)中,每个方法都用“ using”括起来了-这意味着每次调用该类中的方法时,都会创建一个上下文。 因此,如果我要从HomeController.cs中的同一Action调用Database.cs中的2个方法-这是否意味着将创建2个上下文?

像这样在Database.cs中声明私有字段会更好吗:

private Entities db = new Entities()

并让Database.cs类中的每个方法都可以访问它吗? 哪种方法最好?

我当前的实现(我将仅包括方法Verify,但是Database类中有很多方法):

HomeController.cs

    [AllowAnonymous]
    public class HomeController : Controller
    {
        private IDatabase Database;

        public HomeController()
        {
            this.Database = new Database();
        }

        [HttpGet]
        public ActionResult Verify(string id)
        {
            if (Database.VerifyUser(id))
            {
                return View();
            }
            else
            {
                ViewBag.Error = "There was an error with the verification process";
                return View();
            }
        }
    }

数据库.cs

public class Database : IDatabase
{
... some other methods ...
    public bool VerifyUser(string verificationHash)
    {
        using (Entities db = new Entities())
        {
            var userToVerify = db.VerifyUser(verificationHash);
            int count = userToVerify.Count();
            if (count == 1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}

db.VerifyUser(..)-这是对存储过程的调用

是的,这意味着有两个DbContext实例。 更好的方法是在数据库类中有一个DbContext实例,然后在所有方法中使用该实例。

public class Database : IDatabase, IDisposeable
{
    private Entities db;
    public Database()
    {
        db = new Entities()
    }

... some other methods ...
    public bool VerifyUser(string verificationHash)
    {
        var userToVerify = db.VerifyUser(verificationHash);
        int count = userToVerify.Count();
        if (count == 1)
        {
            return true;
        }
        else
        {
            return false;
        }        
    }

    public void Dispose()
    {
        db.Dispose()
    }
}

然后,当您从数据库实例完成时,将其处置,它将处置DbContext

public class HomeController : Controller
{
    private IDatabase Database;

    public HomeController()
    {
        this.Database = new Database();
    }

    [HttpGet]
    public ActionResult Verify(string id)
    {
        using(this.Database)
        {
            if (Database.VerifyUser(id))
            {
                return View();
            }
            else
            {
                ViewBag.Error = "There was an error with the verification process";
                return View();
            }
        }
    }   
}

顺便说一句:您可能希望将资源分配到控制器级别。 在这种情况下,您不需要在操作中添加using语句,例如,将其添加到控制器中:

protected override void Dispose(bool disposing)
{
    this.Database.Dispose();
    base.Dispose(disposing);
}

是的,在您的设计中DbContext在每个方法调用中创建和处置。

实际上,将所有数据库操作放在一个类上并一遍又一遍地创建DbContext并不是一个好的解决方案。 将来您可能对该课程有疑问。 它可能及时具有数百种方法,因此很难维护,并且所有实体在语义上都不相互关联,因此可能引起混乱。 我认为将实体类型分为类是更好的解决方案。 例如,您有一个用户,项目,部门。 如果我们将解决方案应用于这些实体,则uml类图将像这样。

Uml设计示例

所有存储库均引用DbContext。 这称为依赖注入。 这意味着dbcontext实例化一次,并通过必要的存储库传递其引用,因此无需重新创建上下文。 此外,还有一个通用存储库,您可以将其放入标准过程。

因此,您可以使用这样的存储库。

[HttpGet]
public ActionResult Verify(string id){

   using(var context = new DbContext())
   {
      var userRepo = new UserRepository(context); 
      //Department repository can be used over the same context.
      var departmentRepo = new DepartmentRepository(context);
      if(userRepo.verifyUser(id)){
         return View();
      }
   }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM