在较小的项目中查看模型和持久性的3种方法 - 我应该使用哪种方法?

时间:2015-12-06 17:08:46

标签: asp.net-mvc controller persistence viewmodel dbcontext

现在,在较小的项目中,我在三种方法之间挣扎。我想选择其中一个一贯使用。

我已经放了示例代码,下面是优缺点。但基本上,这3种方法归结为:

  1. 所有数据库在控制器中工作
  2. 数据库实例从控制器传递到ViewModel,并在那里完成工作
  3. 使用(使用)在ViewModel中创建的数据库,并在那里完成工作
  4. 为什么有经验的开发人员会选择一种方法而不是另一种?

    这些方法有什么好处/缺点 - 作为初学者 - 我可能不知道?

    更新

    我很欣赏这些模式可能不会用于较大的项目,这些项目往往在结构上更复杂。

    但实际上我对使用它们时的不同感兴趣。

    接近一个

    控制器

    中的所有数据库工作和虚拟化流程

    让您轻松掌握简单应用程序的进展情况......

    ...但是'胖'控制器可能会模糊对复杂应用程序的理解。

    MS在MVC模板中使用的默认值

    public class ModelOne
    {
        public int ID { get; set; }
        public string PropA { get; set; }
        public string PropB { get; set; }
        public string PropC { get; set; }
        // etc...
    }
    public class EditModelOnePropAViewModel
    {
        public EditModelOnePropAViewModel(ModelOne model)
        {
            ID = model.ID;
            PropA = model.PropA;
        }
        public string PropA { get; set; }
        public int ID { get; set; }
    }
    
    public class ControllerOne : Controller
    {
        private ApplicationDbContext DB = new ApplicationDbContext() { };
    
    
        [HttpGet]
        public ActionResult Edit(int id)
        {
            var model = DB.ModelOneDbSet.FirstOrDefault(i => i.ID);
            var viewModel = new EditModelOnePropAViewModel(model);
            return View(viewModel);
        }
        [HttpPost]
        public ActionResult Edit(EditModelOnePropAViewModel postedModel)
        {
            if (ModelState.IsValid)
            {
                var model = DB.ModelOneDbSet.FirstOrDefault(i = i.ID == postedModel.ID);
                model.PropA = postedModel.PropA;
                DB.SaveChanges();
                return RedirectToAction("index");
            }
            return View(postedModel);
        }
    }
    

    接近两个

    DB从Controller

    传递到ViewModel

    控制器太薄了#39;和愚蠢的#39;

    因为我们正在使用控制器的数据库实例,所以它将在DB对象上调用它的Dispose()方法。

    public class ModelTwo
    {
        public int ID { get; set; }
        public string PropA { get; set; }
        public string PropB { get; set; }
        public string PropC { get; set; }
        // etc...
    }
    public class EditModelTwoPropAViewModel
    {
        public EditModelTwoPropAViewModel(ApplicationDbContext db, int id)
        {
            ID = id;
            PropA = db.ModelTwoDbSet
                .Where(i => i.ID == id)
                .Select(i => i.PropA)
                .FirstOrDefault();
        }
    
        public void SaveChanges(ApplicationDbContext db)
        {
            var modelTwo = db.ModelTwoDbSet.FirstOrDefault(i => i.ID == ID);
            modelTwo.PropA = PropA;
            db.SaveChanges();
        }
        public string PropA { get; set; }
        public int ID { get; set; }
    }
    
    public class ControllerTwo : Controller
    {
        private ApplicationDbContext DB = new ApplicationDbContext() { };
    
        [HttpGet]
        public ActionResult Edit(int id)
        {
            var viewModel = new EditModelTwoPropAViewModel(DB, id);
            return View(viewModel);
        }
        [HttpPost]
        public ActionResult Edit(EditModelTwoPropAViewModel postedModel)
        {
            if (ModelState.IsValid)
            {
                postedModel.SaveChanges(DB);
                return RedirectToAction("index");
            }
            return View(postedModel);
        }
    }
    

    接近三

    与Two相同,但在ViewModel中使用(使用)创建了数据库。

    public class ModelThree
    {
        public int ID { get; set; }
        public string PropA { get; set; }
        public string PropB { get; set; }
        public string PropC { get; set; }
        // etc...
    }
    public class EditModelThreePropAViewModel
    {
        public EditModelThreePropAViewModel(int id)
        {
            using (var db = new ApplicationDbContext())
            {
                ID = id;
                PropA = db.ModelThreeDbSet
                    .Where(i => i.ID == id)
                    .Select(i => i.PropA)
                    .FirstOrDefault();
            }
        }
    
        public void SaveChanges()
        {
            using (var db = new ApplicationDbContext())
            {
                var modelThree = db.ModelThreeDbSet.FirstOrDefault(i => i.ID == ID);
                modelThree.PropA = PropA;
                db.SaveChanges();
            }
    
        }
        public string PropA { get; set; }
        public int ID { get; set; }
    }
    
    public class ControllerThree : Controller
    {
        [HttpGet]
        public ActionResult Edit(int id)
        {
            var viewModel = new EditModelThreePropAViewModel(id);
            return View(viewModel);
        }
        [HttpPost]
        public ActionResult Edit(EditModelThreePropAViewModel postedModel)
        {
            if (ModelState.IsValid)
            {
                postedModel.SaveChanges();
                return RedirectToAction("index");
            }
            return View(postedModel);
        }
    }
    

1 个答案:

答案 0 :(得分:1)

您的问题太广泛,包含许多不同方面。所以我试着给你一个非常普遍的看法。软件设计没有任何错误或正确。有"项目需求和规格"。但通常它已被接受使用"设计模式和原则"使项目更加健壮,可靠且易于维护,使您的代码能够松散耦合,并具有高度凝聚力。#/ p>

考虑到这些,我会对你的选择给出我的看法:

  1. 所有数据库在控制器中工作:这对小型项目有利,因为未来扩展的可能性很低。对于稍后加入的其他开发人员来说,它易于设置且易于理解。对于需要稍后更改数据库的项目来说,这不好,在这种情况下,您需要重写所有方法,可能还需要重写您的视图。这种方法的另一个缺点是需要添加的每个对象的重复代码。
  2. 数据库实例从控制器传递到ViewModel,并在那里完成工作: 为了理解您的代码,您尝试为项目添加一个层以进行所有数据库操作那里。如果您需要更改数据,数据库或防止重复代码,这是很好的。如果你想要这样,最好在你的解决方案中使用另一个项目,称为"多层架构师",以获得更大的灵活性和"松散耦合"部分。在这种情况下,您可以轻松地将数据库项目替换为其他项目而不必担心您的视图和控制器,在多层架构师中称为表示层。
  3. 使用(使用)在ViewModel中创建的数据库,并在那里完成工作:这不是新方法。拥有"使用块"在你的代码中是关于"线程饥饿" (更多信息here)。
  4. 最后,考虑您的项目需求和规格,设计您的架构并遵循基于"设计模式和原则"的架构。有关设计模式的更多信息,我推荐书和#34;专业ASP.NET设计模式"来自" Scott Millett"。