【问题标题】:How to make POCO work with Linq-to-SQL with complex relationships in DDD如何使 POCO 在 DDD 中与具有复杂关系的 Linq-to-SQL 一起工作
【发布时间】:2011-08-01 18:20:17
【问题描述】:

当我的域模型不是表驱动时,我正在努力寻找一种方法让 POCO 与 Linq-to-Sql 一起工作 - 这意味着我的域对象与数据库架构不匹配。

例如,在我的域层中,我有一个 Appointment 对象,它具有 Recurrence 类型的 Recurrence 属性。这是一个基类,其中包含多个子类,每个子类都基于特定的重复模式。

在我的数据库中,当约会记录与其重复之间始终存在一对一的关系时,拥有单独的 AppointmentRecurrences 表是没有意义的。因此,Appointments 表具有 RecurrenceType 和 RecurrenceValue 列。 RecurrenceType 与 RecurrenceTypes 表具有外键关系,因为重复类型(模式)和 Appointments 表之间存在一对多的关系。

除非有办法在 Linq-to-Sql 中创建这两个模型之间的正确映射,否则我只能手动解决代码中的阻抗不匹配问题。

当使用规范模式查询数据库时,这变得更加困难。例如,如果我想返回当前约会的列表,我可以轻松地创建一个使用以下表达式的规范对象:appt => appt.Recurrence.IsDue。但是,这不会转化为 Linq-to-SQL 空间,因为表达式的源类型不是 L2S 可识别的类型(例如,它不是 L2S 实体)。

那么如何在 Linq-to-SQL 中创建复杂的映射来支持我的域模型?

或者,在这种情况下是否有更好的方法来实现规范模式?我曾考虑过使用由我的域对象和 L2S 实体(通过部分)实现的接口,但由于两个对象图的阻抗不匹配,这是不可能的。

建议?

【问题讨论】:

    标签: linq-to-sql domain-driven-design poco ddd-repositories


    【解决方案1】:

    不幸的是,Linq to SQL 几乎迫使您进入每个表类模型,它不支持将单个实体类映射到多个数据库表。

    更不幸的是,支持更复杂映射的 ORM 非常少,支持并提供良好 LINQ 支持的也几乎没有。我唯一能确定的是 NHibernate(我们在 Entity Framework 方面的经验认为它在这方面确实不比 L2S 好)。

    此外,尝试在 LINQ 表达式中使用规范模式将是一个相当大的挑战。

    即使使用 ORM,即使使用像 NHibernate 这样非常强大的抽象 ORM,仍然需要克服很大的阻抗不匹配。

    【讨论】:

    • 我同意 Brian 的观点,即使用 Expressions 不是问题,而且我已经有了相应的框架。我的问题是阻抗不匹配。我不确定任何人如何才能真正遵循 DDD 的限制,因为我的域对象的结构很可能与数据的存储方式非常不同,因为一个模型行为和另一个存储状态的目标是至少尝试规范化数据。似乎是 MS 的 ORM 计划中的一个重大疏忽,并解释了为什么这么多 DDD 示例使用 NHibernate。
    • 看来我的选择是有限的。如果 L2S 将以每表类的方式生成实体,那么我可以继续按照最初的计划(并以 DDD 方式)创建我的域对象,然后将不匹配问题留给 Repository 类,我想我会现在不得不搁置规范模式。不幸的是,这将执行查询所需的逻辑放入存储库中,这是完全不可取的,但是唉......
    • 是的,MS 工具还没有完全达到一个干净、解耦的域层。
    【解决方案2】:

    post 解释了如何将规范模式与 linq-to-sql 一起使用。这些规范可以链接在一起,从而构建一个表达式树,供您的存储库使用,因此也可以使用 linq-to-sql。

    我还没有尝试实现它,但是 linq-to-entities 版本在我目前正在进行的项目的待办事项列表中。

    【讨论】:

    • 只要您的所有规范仅依赖于可以从 LINQ 转换为 SQL 的逻辑(基本上是对直接在数据库中表示的字段的原始比较),就可以正常工作。一旦您的需求超出了最简单的场景,这将一蹴而就。
    • 是的,我熟悉规范模式,我打算使用该模式,以便我可以在我的领域层中定义规范并将它们传递到将使用它们的数据层解决任何搜索。做到这一点的唯一方法是使用完整的 POCO,这可以通过 L2S 使用 XML 映射文件,但必须构造我的域对象以匹配数据库模式,以便 L2S 可以映射它们对我来说是一个真正的问题,并且破坏了 DDD,imo .毕竟,我不在乎创建域对象时数据库的规范化程度,但现在看来我确实在乎。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多