【问题标题】:Confusion between DTOs (linq2sql) and Class objects!DTO(linq2sql)和类对象之间的混淆!
【发布时间】:2010-11-22 07:47:45
【问题描述】:

我已经成功地使用了 linq2sql 和 linq DTO(由 linq2sql 创建的类)......

我很困惑,我有更新旧应用程序的任务,我可以看到我的 DTO 将按应有的方式使用....来传输日期

我正在使用存储库模式,所以我通过 linq2sql dtos 将数据从存储库传递到服务...一旦我在服务层(这基本上是我的业务逻辑),那么我需要传递类对象..

这些类对象基本上是 dto 的镜像(或多或少)——在某些地方有一些变化,但大体相同..

所以回到手头的问题! - 仅使用 dtos 将数据从存储库传输到服务层是一种很好的做法......一旦在服务层(业务逻辑)中,我应该将我所有的 dtos 映射到那里的类对象计数器部分(当然使用自动映射器! !)

我的另一个选择是继续使用类对象之类的 DTOS,并将它们从一个方法传递到另一个方法,并作为返回类型等,但我觉得这是不好的做法,我一直在想我应该应用哪种方法?

非常感谢任何帮助

谢谢

【问题讨论】:

    标签: c# linq-to-sql repository-pattern automapper dto


    【解决方案1】:

    这是我的看法: 在处理任何非平凡的应用程序时。使用 linq2Sql 对象作为域模型是一个非常糟糕的主意。我将 linq2Sql 视为 ORM,仅此而已。数据库(与 linq2Sql 有直接对应关系)是 data 的规范化。类(在 OOAD 意义上)是行为(不是数据)的规范化。

    [这些类对象基本上是镜像]...

    我在使用 linq2Sql 构建应用程序时遇到了这个问题。让我们现实一点......大多数业务线应用程序都是美化的 CRUD 应用程序。因此,应用程序的大部分实体将直接对应于数据库表并不是不可能的。 我不想直接绑定到生成的 DTO,但同时我不希望在我的应用程序中乱扔重复的类。

    所以这是我的解决方案:
    我“编程到一个接口”。

    假设我有一个PersonDto(Dto 代表数据传输对象),其属性为FirstName, LastName, Age(与数据库列直接相关)。

    我创建了一个 IPerson 接口并让我的 PersonD 来实现它。

    [Table(Name="Persons")] internal class PersonDto : IPerson { .... }

    我的存储库方法将接收并检索 IPerson,而不是 Linq2Sql 类。

    IPerson somePerson = _repository.Get(someGuid); somePerson.FirstName = "SomeName"; _repository.Save(somePerson);

    这种方法对我来说非常有效。每当我觉得我需要偏离 DTO 时,我可以很容易地做到这一点,因为代表我的对象的接口而不是 DTO。

    一些通用指针: 手动构建您的 DTO...我知道这听起来很疯狂,但您会发现它非常适合自上而下的测试驱动开发方法。您的 DTO (linq2Sql) 对象将非常轻巧,并且将对 .dbml 设计器之外的更改开放。

    将 DTO 和 DataContext 保持在内部。没有理由公开公开您的 dto(假设您有存储库和域对象的公共接口)。这样做将强制在您的域模型和数据访问之间进行逻辑分离。

    将所有数据访问层放在一个单独的项目中(再次强制执行这种分离)。

    将您的接口声明放在一个单独的项目中(这将确保您不会遇到任何循环引用)。

    希望这会有所帮助...

    【讨论】:

    • 我喜欢这个想法...唯一的问题是在 MVC 中,控制器无法为 add 方法接收接口。这使得接口对于 MVC 来说相对无用。你是如何处理这个问题的,因为我真的很想这样做。
    • 添加方法?你能详细说明一下吗,我目前正在使用这种方法和 aspmvc 并且没有任何问题。
    • "控制器不能为 add 方法接受接口",只需创建一个实现该接口的视图模型。它可以驻留在 Web 项目中,因为它只是一个有助于促进与视图交互的对象。
    【解决方案2】:

    尽管我的意图略有不同,但我实际上对这个主题也有类似的问题。建议是使用 Linq2SQL 类作为域对象并利用其他人提到的部分类。我主要关心的是这些对象的形状(即属性名称),以及类成员的可访问性(例如,私有与受保护)。

    对象的形状甚至可访问性都可以通过使用 t4 模板来解决,其中 Damien Guard 将 T4 模板放在一起,允许您控制 Linq2Sql 将为您生成的类的形状。这可以在这里看到T4 template for Linq2SQL

    这是我要研究的方法,看看它是否能解决我的顾虑。此外,如果您的服务层可以接受方法参数的接口,您还可以通过 Linq2SQL DTO 周围的接口包装器来控制服务层可以访问的内容。

    希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      这是我见过的关于该主题的最佳讨论之一:

      http://blog.wekeroad.com/blog/linqtosql-momma-said-knock-you-out/

      最后,耦合和内聚的决定取决于具体情况,您必须决定什么最适合您的情况。

      当您的应用程序超出 LinqToSql 时,抽出 LinqToSql 并在其位置插入另一个 ORM 会有多容易?这是你必须认真考虑的事情。

      一般来说,尽量减少您的业务层对 LinqToSql 的了解。 LinqToSql 应该对你的 UI 层完全隐藏(你的业务层构成了这个屏蔽的很大一部分)。使用 LinqToSql 很容易走上错误的架构路径,而事后又很难回到正确的路径上。

      【讨论】:

        【解决方案4】:

        linq2sql 设计器生成的类是部分类,因此您可以扩展这些类并将您的业务逻辑直接放入其中。这个想法是 linq 用于持久化/重建这些实体,因此您可以避免您正在谈论的那种映射。

        【讨论】:

        • 一旦开始将业务逻辑嵌入到 LinqToSql 分部类中,以后就很难将它们解耦。如果您不想要/不需要业务层,那很好,但这并不总是正确的方法。此外,在将来的某个时候(可能有必要也可能没有必要)用不同的 ORM 替换 LinqToSql 是很困难的。
        • 重点是,您的 linqToSql 实体是“业务层”的一部分,并且存储库用于在数据库中获取/保存它们。是的,与 linq 设计器有一些耦合,但这是一个不同的问题。
        • @Lee:不,您不应该将 linq2sql 用于您的业务层。这是一个很棒的对象关系映射器,但我强烈建议您不要落入那个陷阱。您的数据库是数据的规范化,您的业务层是行为的规范化。
        猜你喜欢
        • 2014-05-18
        • 2010-11-30
        • 1970-01-01
        • 2013-07-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-03
        • 2016-09-22
        相关资源
        最近更新 更多