5

我一直在阅读教程(特别是使用 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 to Entities 仅支持无参数构造函数和初始化程序。

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

4

2 回答 2

4

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

这些问题并不一定以任何方式与 ASP.NET MVC 相关联。ASP.NET MVC 基本上没有提供有关如何进行模型/数据访问的指导,并且 ASP.NET MVC 的大多数示例和教程都不是具有生产价值的模型实现,而实际上只是最小的示例。

看来你在正确的轨道上,继续前进。

最后,您主要将 Entity Framework 用作代码生成器,它不会生成非常有用的代码,因此您可能希望查看更符合您的要求的其他代码生成器或工具或框架。

于 2009-09-20T10:02:03.033 回答
4

_someRepositoryOrService.Add(id, classA, classB);

我会说你将你的存储库与表示层结合起来。这不应该。您的存储库应仅与实体一起使用。接下来,注意您的 Add 方法

public void Add(int id, ClassA classA, ClassB classB)

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

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

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

另请查看Jimmy Bogard(ASP.NET MVC In Action 的合著者)关于 ViewModels 的这篇优秀文章。这可能会帮助您自动映射。它还提出了一种相反的技术——让你的控制器与实体一起工作,而不是 ViewModels!自定义动作过滤器和模型绑定器确实是消除不属于控制器的例程的关键,而是视图和控制器之间的基础设施细节。例如,这里是我如何自动化实体检索。以下是我如何看待控制器应该做什么。

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

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

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

One more thing. Read about Domain Driven Design, look for articles, learn from them, but you don't have to follow everything. These are guidelines, not strict solutions. See if your project can handle that, see if you can handle that, and so on. Try to apply this techniques since they're generally the excellent and approved ways of doing development, but don't take them blindly - it's better to learn along the way than to apply something you don't understand.

于 2009-09-30T20:23:46.110 回答