【问题标题】:WCF Contracts from Entity Framework?来自实体框架的 WCF 合同?
【发布时间】:2009-02-25 14:56:43
【问题描述】:

我在这个问题上想出了很多死胡同。据称,.NET 3.5 SP1 支持 WCF 合同中的 ADO.NET Entity Framework 实体。但是当我寻找关于它的可靠信息时,我并没有得到很多答案。我在 MSDN 线程上找到了这个 sn-p。有人对这个有经验么? [DataContract] 发生了什么?这就是它的全部吗?为什么这方面的资料这么少?

这是来自 Microsoft 的 Tim Mallalieu 的答案。

在实体框架中生成的实体类型默认是数据契约。 如果我要在实体设计器中创建一个简单的模型,如下所示: 购物车实体类型默认是一个 DataContract,所有属性都被注释为数据成员。然后我们可以在 WCF 服务中使用它,如下所示:

[ServiceContract]

public interface IService1

{
    [OperationContract]
    Cart[] AllCarts();
}



public class Service1 : IService1

{
    public Cart[] AllCarts() 

    {
        using (MSPetShop4Entities context = new MSPetShop4Entities())

        {
            var carts = from c in context.Carts select c;
            return carts.ToArray();
        }
    }
}

由于实体是 DataContract,您现在可以根据需要滚动服务并通过网络发送这些服务。

【问题讨论】:

    标签: wcf entity-framework


    【解决方案1】:

    我建议您不要直接返回实体。不幸的是,Microsoft 选择将特定于实现的数据作为实体的 DataContract 的一部分。这不会与其他平台互操作,并且即使在 .NET 版本之间也可能无法互操作。

    相反,我建议您遵循数据传输对象模式,只返回作为实体中数据副本的 POCO 类,没有任何行为。您可以返回此类类的列表以表示表格等。

    【讨论】:

    • 我已经考虑过这一点,但令人难以置信的是这会产生多少工作量。从表面上看,上面的简单代码似乎并没有模糊关注点的分离。如果我要接受 EF,我不是“一分钱,一英镑”吗?换句话说,我已经脱离了 POCO 的领域。没有?
    • 好的,约翰,对不起,我错过了你的意思。您是说返回的对象除了简单数据之外还有“其他东西”。这不好。您有什么好的方法可以生成 DTO 合同声明吗?
    • 我的一部分希望 MS 提供 WCF 的一个子集,该子集的互操作性较低,但对数据实体、Linq 等更友好,但类似的东西仍然会增加我不确定的耦合好主意...
    • 有什么方法可以准确地查看电话返回的内容?在我看来,如果 EF 只是使用 WCF 标准对实体和属性进行注释,那么 WCF 如何返回除 WCF 标准之外的内容? EF 会破坏 WCF 吗??
    • 遵循 John 的回复可以使您免于将来出现其他问题(即 ObjectContext)。尝试将实体框架视为语言集成的数据库,您会更安全。 wizardsofsmart.net/patterns/…
    【解决方案2】:

    “共享接口而不是类型”原则的前提是您不拥有线路的两端和/或您正在编写面向公众的 Web 服务。 WCF 可以在绝对不是的情况下使用(并且被使用)。许多企业 n 层体系结构都有一个 WCF 前端的应用程序层,以促进负载平衡等。在这些情况下,共享类型是完全有效的,而且实际上是需要的。

    【讨论】:

      【解决方案3】:

      你可以用简单的方法使用ADO.NET Data Services

      【讨论】:

      • 最后我确实做到了。我希望从长远来看这不是一个错误。到目前为止,我看到的缺点是我最终在客户端而不是模型端实现了存储库模式。我对此不满意,以后可能不得不重构。
      • ADO.NET 数据服务的危险在于很难遵循 DDD 方法。您应该将 ADO.NET 数据服务视为:数据服务。如果您需要一组更强大的模型服务,则需要单独创建。
      • 即使使用最新版本的 ADO .NET 数据服务和 EFCF 4.1,它仍然受到严格限制。例如,不支持来自 LINQ 的聚合运算符,包括 Distinct()。如果您需要的不仅仅是 CRUD 功能,您应该远离数据服务。
      【解决方案4】:

      回复 cmets 的更多细节:

      EF 生成的类存在几个问题。我现在正在查看带有 SalesOrderHeader 和 SalesOrderDetail 的 AdventureWorks 示例。 SalesOrderDetail 实体同时具有“SalesOrderHeader”和“SalesOrderHeaderReference”属性,均标记为 DataMembers。这看起来像一个错误,因为“SalesOrderHeader”属性也被标记为 [XmlIgnore] 和 [SoapIgnore]。

      另外,首先考虑是否要将链接序列化回父 SalesOrderHeader。此外,究竟应该序列化什么? SOAP 不支持以可互操作的方式引用。

      最后,实体的基类也是数据契约。然而,它们与您返回的 数据 无关 - 它们纯粹是一个实现工件。

      简而言之,微软在这件事上搞砸了。他们没有考虑清楚。

      关于生成 DTO 类的方法,我建议研究各种代码生成工具,例如 CodeSmith。您可以自己编写代码来执行此操作;我在以前的职位上也是这样做的。生成 DTO 的好处是您还可以生成与 DTO 相互转换的方法。

      关于开销,与通过网络发送数据所需的时间相比,在内存中移动一些数据的开销微不足道!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-10
        相关资源
        最近更新 更多