我有一个WCF数据服务层,它暴露了POCO T4模板生成的POCO实体。这些POCO实体是在他们自己的项目(即Company.ProjectName.Entities)中创建的,因为我想尽可能地分享它们。
我在另一个项目(Company.ProjectName.Clients)中有一组接口,它们通过向Company.ProjectName.Entities.dll添加程序集引用来引用这些POCO类型。这些接口的一个实现是.NET客户端,我想使用WCF数据服务客户端库来使用该服务。
我使用添加服务引用添加服务引用。这生成了DataServiceContext客户端类和服务使用的POCO实体。但是,添加服务引用实用程序生成的这些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类型。但这听起来有点黑客。
有没有更好的解决方案,任何人都提出或有任何建议?
答案 0 :(得分:1)
好的,在开始赏金后的几个小时,我发现为什么它在我的结束时没有按预期工作。
事实证明,共享过程非常简单。所有需要做的就是使用[DataServiceKey]
属性标记模型类。 This article在“公开其他数据模型”部分
考虑到这一点,我试图做的是以下内容:
当我尝试这个时它不起作用,给我以下错误:
客户端和服务之间存在类型不匹配。类型 {MyType}不是实体类型,而是类型 响应有效负载表示实体类型。请确保类型 在客户端上定义的匹配服务的数据模型,或更新 客户端上的服务引用。
此问题是由项目C(使用System.Data.OData程序集上的库存实现)与调用服务的客户端项目B(使用Microsoft.Data.OData程序集)之间的版本不匹配引起的。 packages)。通过匹配两端的版本,它第一次工作。
在所有这些之后,仍然存在一个问题:服务引用过程仍未检测到要共享的模型,这意味着代理正在照常创建。这导致我选择退出自动服务集成机制,而不是强迫我继续使用我自己的简单类来作为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; }
}
}
这很简单,因为我只在readonly模式下使用该服务。我仍然希望使用服务引用功能,可能避免将来的维护问题,在这个简单的情况下由硬编码的EntitySet名称证明。目前,我正在使用此实现并完全删除了服务引用。
我真的希望看到这与服务参考方法完全集成,如果有人可以共享解决方法,但这种自定义方法可以满足我们当前的需求。