2

我有一个 WCF 数据服务层,它公开了 POCO T4 模板生成的 POCO 实体。这些 POCO 实体是在他们自己的项目(即 Company.ProjectName.Entities)中创建的,因为我想尽可能地分享它们。

我在另一个项目(Company.ProjectName.Clients)中有一组接口,它们通过向 Company.ProjectName.Entities.dll 添加程序集引用来引用这些 POCO 类型。这些接口的实现之一是 .NET 客户端,我想使用 WCF 数据服务客户端库来使用该服务。

我使用了添加服务引用来添加服务引用。这会生成服务使用的 DataServiceContext 客户端类和 POCO 实体。但是,由 Add Service Reference 实用程序生成的这些 POCO 类型现在具有不同的命名空间(即 Company.ProjectName.Clients.Implementation.WcfDsReference)。

这意味着接口中定义的 POCO 类型不能被实用程序生成的类型使用,而无需强制转换或映射。

即假设我有:

 1. POCO Entity:     Company.ProjectName.Entities.Account
 2. Interface:       interface IRepository<Company.ProjectName.Entities.Account>{....}
 3. Implementation:  ServiceClientRepository : IRepository<Company.ProjectName.Entities.Account>
 4. WcfDsReference:  Company.ProjectName.Clients.Implementation.WcfDsReference
          &          Company.ProjectName.Clients.Implementation.WcfDsReference.Account


   Let's say I want to create a DataServiceQuery query on the Account, I won't be able to do this:

   var client = new WcfDsReference(baseUrl);
   var accounts = client.CreateQuery<Company.ProjectName.Entities.Account>(...)

      OR:         client.AddToAccounts(Company.ProjectName.Entities.Account)

   , because the CreateQuery<T>() expects T to be of type            &       Company.ProjectName.Clients.Implementation.WcfDsReference.Account

我目前要做的是将正确的实体传递给 CreateQuery 方法,并且必须将结果映射回接口可以理解的类型。(可以使用映射器,但似乎不是一个好的解决方案。)

所以问题是,有没有办法让 Add Service Reference 实用程序生成使用 Company.ProjectName.Entities 命名空间中的 POCO 类型的方法?

我正在考虑的一种解决方案是不使用该实用程序来生成 DataServiceContext 和其他类型,而是创建我自己的。

另一种解决方案是更新IRepository<T>界面以使用实用程序生成的 POCO 类型。但这听起来有点骇人听闻。

有没有人提出过更好的解决方案,或者有什么建议?

4

1 回答 1

1

好的,在开始赏金几个小时后,我发现了为什么它没有按预期工作。

事实证明,共享过程非常简单。需要做的就是用[DataServiceKey]属性标记模型类。本文在“公开另一个数据模型”部分中很好地解释了该过程

考虑到这一点,我想做的是以下几点:

  1. 将模型放在单独的类库项目 C 上,与 web 应用程序项目 A 和 B 共享
  2. 在项目 A 上创建数据服务
  3. 在项目 B 上添加服务引用
  4. 从服务引用中删除生成的模型代理,并更新它以使用我在项目 C 中的模型类
  5. 将 DataServiceKey 属性添加到模型,指定正确的键

当我尝试这个时它不起作用,给我以下错误:

客户端和服务之间存在类型不匹配。{MyType} 类型不是实体类型,但响应负载中的类型表示实体类型。请确保客户端上定义的类型与服务的数据模型匹配,或者更新客户端上的服务引用。

此问题是由项目 C(使用 System.Data.OData 程序集上的库存实现)和调用服务的客户端项目 B(使用中的 Microsoft.Data.OData 程序集)之间的版本不匹配引起的. 通过匹配两端的版本,它第一次工作。

毕竟,一个问题仍然存在:服务引用过程仍然没有检测到要共享的模型,这意味着代理正在像往常一样创建。这导致我选择退出自动服务集成机制,而是迫使我继续使用我自己的一个简单类作为 Wcf 数据服务的客户端。基本上,它是通常自动生成的类的一个经过大量修剪的版本:

using System;
using System.Data.Services.Client;
using System.Data.Services.Common;
using Model;

public class DataServiceClient : DataServiceContext
{
    private readonly Lazy<DataServiceQuery<Unit>> m_units;

    public DataServiceClient(Uri _uri)
        : base(_uri, DataServiceProtocolVersion.V3)
    {
        m_units = new Lazy<DataServiceQuery<Unit>>(() => CreateQuery<Unit>("Units"));
    }

    public DataServiceQuery<Unit> Units
    {
        get { return m_units.Value; }
    }
}

这很简单,因为我只在只读模式下使用该服务。不过,我仍然希望使用服务引用功能,这可能会避免未来的维护问题,正如在这个简单案例中硬编码的 EntitySet 名称所证明的那样。目前,我正在使用这个实现并完全删除了服务引用。

如果有人可以分享解决方法,我真的很希望看到它与服务参考方法完全集成,但是这种自定义方法对于我们当前的需求是可以接受的。

于 2013-09-02T16:47:41.503 回答