【问题标题】:WCF DataServices & Mapped DTOsWCF 数据服务和映射的 DTO
【发布时间】:2012-08-07 18:32:38
【问题描述】:

我有一个带有域模型的服务,我想向客户公开数据。服务有典型的架构:数据库、ORM(EF)、带有领域模型的业务层。

我想使用 WCF DataServices 向客户端公开数据,但我无法将数据对象从域模型发送到客户端。我将使用 DTO 与客户端交互,并且我有 dto 数据对象映射。

DataServices 具有反射提供程序,在这种情况下似乎很好(让我们考虑只读方案)。但是反射提供者需要 IQueryable<dto> 属性被暴露。这就是问题所在。所以我看到了以下解决方法:

  1. 加载所有域对象,将它们全部映射到 dtos 并返回结果 dtos。如果存在许多域对象,则方法非常糟糕。
  2. 创建“linq2dto”提供程序并动态生成对应的“linq2EF”查询,在查询实现点从数据库获取数据对象并执行映射。听起来不错,但在我看来,这是一项复杂的任务。

各位,我需要帮助。我不想编写(和支持!)一个新的 linq 提供程序。可能有一些我可以使用的“通用 linq2anyware”实现?

另一方面,我真的不能向客户端公开数据对象并使用 DataServices EF 提供程序。有没有一些简单的方法来实现这种映射?

【问题讨论】:

  • 先问一个显而易见的问题:你真的需要 DTO 吗?使用 EF 编写代码并不能充分满足您的需求?

标签: c# wcf-data-services dto


【解决方案1】:

简而言之,手动编写每个 DTO。

可能不是您正在寻找的答案,但这是我的建议。如果不能暴露实际类型,手动写一个轻量级的卫星类型,例如

class Foo
{
    //large domain type

    FooDTO ToDTO()
    {
        return new FooDTO(...)
    }
}

class FooDTO
{
    //lightweigh
}

我还没有看到任何 LINQ 提供程序可以帮助您制作通用转换器,但这可能是因为我的经验有限。反对使用泛型转换器的另一个论点是域类型可能需要非常具体的指令,说明轻量级对象中包含什么以及排除什么。

或者,您可以尝试编写一个通用类,该类使用反射来遍历所有公共属性并返回一个序列化对象,但是您如何知道线路另一端的对象类型(如果您无法使用您的域类型)?

【讨论】:

    【解决方案2】:

    不幸的是,如果您真的打算使用 DTO,您将需要承担将查询树转换为 EF 可以使用的工作的工作。这很可能会让您进入自定义提供程序领域,这是您必须处理的另一个问题。

    对于查询树翻译,您可能会查看 re-linqIQ toolkit 之类的内容。

    我们能否在 cmets 中就您为什么需要 DTO 的问题进行一次简短的对话?如果其他人也能理解这个细节,我认为这个问题对其他人会更有用。

    【讨论】:

    • 我使用 DTO 的原因如下: 1. 不同的服务器和客户端代码。它将简化代码重构,因此我可以更改服务器数据对象,更正映射并更改客户端对象 2. 从客户端隐藏服务器端代码(将数据对象映射到 db 表) 3. 添加一个扩展点以有机会拦截客户端调用并以特定方式处理它们
    • 我不确定这是否完全回答了您的观点,但我将回复如下: 1. 客户端代码实际上不同于服务器代码 - 您可以将自己的 POCO 带到 WCF 数据服务或如果您使用添加服务引用,我们将为您生成代理类。如果您在客户端使用自己的 POCO,则分别重构服务器和客户端可能会更容易。 2. EF Code First 在处理对象-RDBMS“阻抗不匹配”方面已经做得很好;如果你还没有,你应该玩这个。 3.你看过QueryInterceptors/ChangeInterceptors吗?
    • @Sergey:关于您提供的 3 个原因,您选择了哪条路径?我现在也处于同样的情况。您是否按照 Mark 的建议同时使用客户端和服务器端的 POCO?如果有,您是否遇到过任何安全问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-29
    • 2021-10-28
    • 1970-01-01
    • 2014-11-18
    • 2012-11-23
    • 2011-03-02
    相关资源
    最近更新 更多