【发布时间】:2015-03-03 15:36:32
【问题描述】:
我正在为我正在构建的网站编写大量基本的 CRUD 视图和控制器逻辑。到目前为止,我已经在控制器中编写了大部分代码,这包括通常的验证、输入清理和错误处理。我应该在我的控制器中编写我所有的 DB I/O 代码吗?或者我应该将一些移到我的 DbContext 吗?我问这个,因为我听说过控制器类与模型类之间应该发生多少冲突的观点?将 Db 上下文的实例传递出控制器是否合适?或者我应该在 DbContext 上使用扩展类吗?
例如:
public ActionResult Create(ThingViewModel vModel)
{
try
{
if (ModelState.IsValid)
{
var nm = vModel.ToActualModel();
nm.RelatedThing = nm.RelatedThingId == null ?
null : db.RelatedThings.Single(v => v.Id == nm.RelatedThingId);
nm.UtcCreatedOn = DateTime.UtcNow;
db.Thing.Add(nm);
db.SaveChanges();
var successMessage = "You have created a new Thing!";
return RedirectToAction("Index", new { successMessage = successMessage });
}
else
{
ViewBag.EntityName = "Thing";
ViewBag.ControllerName = "Thing";
ViewBag.Title = "Admin | Thing - Create";
return View("~/Views/Thing/Create.cshtml", vModel);
}
}
catch(Exception e)
{
var errorMessage = "An error occured when creating a new thing!";
return RedirectToAction("Index", new { errorMessage = errorMessage });
}
}
这应该变成:
public ActionResult Create(ThingViewModel vModel)
{
try
{
if (ModelState.IsValid)
{
db.CreateNewThing(vModel) // Defined elsewhere
var successMessage = "You have created a new Thing!";
return RedirectToAction("Index", new { successMessage = successMessage });
}
else
{
ViewBag.EntityName = "Thing";
ViewBag.ControllerName = "Thing";
ViewBag.Title = "Admin | Thing - Create";
return View("~/Views/Thing/Create.cshtml", vModel);
}
}
catch(Exception e)
{
var errorMessage = "An error occured when creating a new thing!";
return RedirectToAction("Index", new { errorMessage = errorMessage });
}
}
在 DbContext 内部:
public bool CreateNewThing(ThingViewModel vModel)
{
//Thing Creation logic
Things.Add(thing);
SaveChanges();
}
为了澄清,我想为每个实体编写一次创建/编辑/删除逻辑,并能够在其他控制器中使用它们。因此,如果我有Person 和Pet 实体以及PersonController 和PetController,则有时需要将包含List<PetViewModel> 的PersonViewModel 写入数据库:Person 需要与每个Pet 一起创建。但是,PetController 已经定义了public ActionResult Create(PetViewModel vm),但我不能从PersonController 内部使用它来将新的Pet 写入数据库。所以,我想将Create(PetViewModel vm) 的数据库逻辑移到其他地方,我可以从其他控制器内部访问它。我要把它移到哪里?将我的DbContext 的引用从控制器传递给静态辅助方法public static bool CreateHelper(DbContext db, PetViewModel vm) 是否合适?
【问题讨论】:
-
绝对不要抽象为
Things.Add(thing);,这就是所谓的存储库模式,理智的人认为它是一种反模式。 -
Things.Add(thing) 已在 DbContext 类中定义,我不会编写它。您是否熟悉 EntityFramework ORM,因为我很确定它本质上实现了存储库模式。
-
是的。确实如此,这就是为什么在它之上实现自己的存储库是零意义的,抱歉,在我的第一条评论中,我的意思是说将 EF 抽象到存储库中是一种反模式。
-
有道理,然后从它的声音中,您确认了我最初的预感,以使助手远离我的 DAL。但我想知道是否应该将它们放在关联的控制器中,或者作为单独的辅助类。
-
我有一个 C# 聊天室中的一个人写的东西的链接,它基本上是 EF 的一个小包装器,让您可以控制哪些集合是可访问的。你可以看看here。这是一个工作单元实现,如果您以前听说过,它与 EF 配合得很好。
标签: c# asp.net asp.net-mvc entity-framework