我已经阅读了教程(特别是使用 Linq-To-Entities 的教程)并且了解基本概念,但是有些事情给我带来了问题。

这些教程通常只涉及简单的模型和表单,仅使用基本的创建、更新和删除语句。我的有点复杂,我不确定我是否以正确的方式处理这个问题,因为当需要处理六个数据库对象的关系时,教程就不再有帮助了。

对于post方法,执行CRUD操作的常用方式

entities.AddToTableSet(myClass);
entities.SaveChanges();

不会做我想做的事,因为完全实现的类没有被发布到控制器方法。我可以发布单个字段、表单集合或多个 DTO 对象,然后调用服务或存储库上的方法来获取从表单发布中收到的信息,以及它需要查询或创建自身的信息,然后从所有这些事情,创建我可以保存的数据库对象。

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Add(int id, [Bind(Exclude = "Id")] ClassA classA,
                        [Bind(Exclude = "Id")]ClassB classB)
{
   // Validation occurs here

   if(!ModelState.IsValid)
      return View();

   try
   {
      _someRepositoryOrService.Add(id, classA, classB);
      return RedirectToAction("Index", new { id = id });
   }
   catch(Exception ex)
   {
      // Logging and exception handling occurs here
   }
}


public void Add(int id, ClassA classA, ClassB classB)
{
    EntityA eA = new EntityA
    {
        // Set a bunch of properties using the two classes and
        // whatever queries are needed
    };

    EntityB eB = new EntityB
    {
        // Set a bunch of properties using the two classes and
        // whatever queries are needed
    };

    _entity.AddToEntityASet(eA);
    _entity.AddToEntityBSet(eB);
    _entity.SaveChanges();
}

我是否正确处理了这个问题,或者我是否在破坏框架?我实际上从未直接使用实体对象,每当我查询一个实体对象时,我都会将所需的信息放入 DTO 中,并以此为基础创建我的视图。创作也是如此。这是允许的,还是我避免直接​​使用实体违背了使用框架的目的?

编辑:我还担心这种方法,因为它需要空构造函数才能正确执行 LINQ 查询,因为出现以下错误消息:

LINQ中仅支持无参数的构造函数和初始化器。

这不是什么大问题,因为我很少需要构造函数中的逻辑,但是没有构造函数而只有公共属性是一个问题吗?

有帮助吗?

解决方案

_someRepositoryOrService.Add(id, classA, classB);

我想说你将你的存储库与表示层结合起来。这不应该是。您的存储库应该仅适用于实体。接下来,注意您的 Add 方法如何

公共无效添加(int id,ClassA类A,ClassB类B)

打破了关注点分离 (SoC)。它执行两项任务:

  1. 将视图数据映射到实体
  2. 保存到存储库

显然第一步应该在表示层完成。为此考虑使用模型绑定器。它还可以帮助您解决构造函数问题,因为您的模型绑定器可以了解构造要求。

还检查这个优秀的 邮政 作者:Jimmy Bogard(《ASP.NET MVC In Action》的合著者)关于 ViewModel 的内容。这可能会帮助您自动映射。它还提出了一种相反的技术 - 让您的控制器与实体一起工作,而不是 ViewModel!自定义操作过滤器和模型绑定器确实是消除不属于控制器而是视图和控制器之间的基础设施细节的例程的关键。例如, 这里这就是我如何自动化实体检索。 这里这就是我对控制器应该做什么的看法。

这里的目标是让控制器满足于管理业务逻辑,抛开所有不属于您业务的技术细节。您在这个问题中谈论的是技术限制,并且您让它们泄漏到您的代码中。但是您可以使用 MVC 工具将其迁移到基础架构级别。

更新:不,存储库不应该处理表单数据,这就是我所说的“与表示耦合”的意思。是的,存储库位于控制器中,但它们不适用于表单数据。您可以(不是应该)使表单与“存储库数据”一起使用 - 即实体 - 这就是大多数示例所做的,例如NerdDinner - 但不是相反。这是因为一般经验法则 - 较高层可以与较低层耦合(表示与存储库和实体耦合),但低层不应该与较高层耦合(实体依赖于存储库,存储库依赖于表单模型等) )。

第一步应该在存储库中完成,这是正确的 - 只是从 ClassX 到 EntityX 的映射不属于该步骤。这是绘图问题——基础设施。参见示例 关于映射的问题,但通常如果你有两层(UI 和存储库),他们不应该关心映射 - 映射器服务/帮助程序应该关心。除了 Jimmy 的博客之外,您还可以阅读 ASP.NET MVC In Action 或简单地查看他们的 CodeCamp服务器 了解它们如何使用传递给控制器​​构造函数的 IEntityMapper 接口进行映射(请注意,这是比 Jimmy Bogard 的 AutoMapper 更手动且工作量更少的方法)。

还有一件事。阅读有关领域驱动设计的内容,查找文章,从中学习,但您不必遵循所有内容。这些是指导方针,而不是严格的解决方案。看看你的项目是否可以处理这个问题,看看你是否可以处理这个问题,等等。尝试应用这些技术,因为它们通常是优秀且经过认可的开发方法,但不要盲目采用它们 - 沿途学习比应用您不理解的东西更好。

其他提示

我会说使用的DTO并用自己的数据访问方法包装实体框架和业务层是一个伟大的路要走。你可能最终编写大量的代码,但它不是假装的实体框架生成的代码更好的架构是业务层。

这些问题是不是真的不必拘泥于ASP.NET MVC以任何方式。 ASP.NET MVC提供了基本上就怎么办模型/数据访问和大多数样本和教程ASP.NET MVC都没有生产价值模型实现,但其实只是很小的样品没有指导。

好像你是在正确的轨道上,继续前进。

在最后,你正在使用实体框架主要是作为一个代码生成器不产生非常有用的代码,所以你可能想看看其他的代码生成器或工具或框架,更符合您的要求。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top