2011-06-16 58 views
4

之间的类型不匹配。那么现在我试图打通我的DataContext的任何数据,我得到这个异常:WCF DataService的(CTP2):有客户端和我使用WCF DataService的CTP2与实体框架4.1服务

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: There is a type mismatch between the client and the service. Type 'Crm.Objects.Segmentation' is not an entity type, but the type in the response payload represents an entity type. Please ensure that types defined on the client match the data model of the service, or update the service reference on the client. at System.Data.Services.Client.AtomMaterializer.MaterializeResolvedEntry(AtomEntry entry, Boolean includeLinks) at System.Data.Services.Client.AtomMaterializer.Materialize(AtomEntry entry, Type expectedEntryType, Boolean includeLinks) at System.Data.Services.Client.AtomMaterializer.DirectMaterializePlan(AtomMaterializer materializer, AtomEntry entry, Type expectedEntryType) at System.Data.Services.Client.AtomMaterializerInvoker.DirectMaterializePlan(Object materializer, Object entry, Type expectedEntryType) at System.Data.Services.Client.ProjectionPlan.Run(AtomMaterializer materializer, AtomEntry entry, Type expectedType) at System.Data.Services.Client.AtomMaterializer.Read() at System.Data.Services.Client.MaterializeAtom.MoveNextInternal() at System.Data.Services.Client.MaterializeAtom.MoveNext() at System.Linq.Enumerable.d_b1 1.MoveNext() at System.Collections.Generic.List 1..ctor(IEnumerable 1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable 1 source) at MangoCrm.Modules.Replication.ReplicaBuilder.GetItems[T](IEnumerable`1 query) at MangoCrm.Modules.Replication.ReplicaBuilder.BeginReplication() at MangoCrm.Modules.Replication.ReplicationWindowControl.b_0() --- End of inner exception stack trace --- at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner) at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) at System.Delegate.DynamicInvokeImpl(Object[] args) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

这里是我的代码:

  var uri = new Uri(webServiceUrl); 
      var service = new DataServiceContext(uri); 
      MessageBox.Show(service.CreateQuery<Segmentation>("DbSegmentations").ToList().Count.ToString()); 

任何帮助吗?

UPDATE 现在确定我发现我的WCF响应包含一个修改的实体对象。那就是:

<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> 
<entry xml:base="http://localhost:99/Services/CrmDataService.svc/" 
     xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" 
     xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" 
     xmlns="http://www.w3.org/2005/Atom"> 
    <id>http://localhost:99/Services/CrmDataService.svc/DbSegmentations(guid'e9854210-85d1-4822-ba70-7e1d3d29cf62')</id> 
    <title type="text"></title> 
    <updated>2011-06-16T15:07:48Z</updated> 
    <author> 
    <name /> 
    </author> 
    <link rel="edit" title="Segmentation" href="DbSegmentations(guid'e9854210-85d1-4822-ba70-7e1d3d29cf62')" /> 
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Companies" 
     type="application/atom+xml;type=feed" 
     title="Companies" 
     href="DbSegmentations(guid'e9854210-85d1-4822-ba70-7e1d3d29cf62')/Companies" /> 
    <category term="Crm.Data.Segmentation" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> 
    <content type="application/xml"> 
    <m:properties> 
     <d:Id m:type="Edm.Guid">e9854210-85d1-4822-ba70-7e1d3d29cf62</d:Id> 
     <d:Name>Promoter</d:Name> 
     <d:Description m:null="true" /> 
     <d:ReplicaInfo m:type="Crm.Data.ReplicaInfo"> 
     <d:CreateDate m:type="Edm.DateTime">2011-06-09T20:35:22.29</d:CreateDate> 
     <d:ModifyDate m:type="Edm.DateTime">2011-06-09T20:35:22.29</d:ModifyDate> 
     <d:CreatedById m:type="Edm.Guid">00000000-0000-0000-0000-000000000000</d:CreatedById> 
     <d:ModifiedById m:type="Edm.Guid">00000000-0000-0000-0000-000000000000</d:ModifiedById> 
     <d:IsDeleted m:type="Edm.Boolean">false</d:IsDeleted> 
     </d:ReplicaInfo> 
    </m:properties> 
    </content> 
</entry> 

这里有一个问题

<category 
term="Crm.Data.Segmentation" 
scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" 
/> 

所以,问题是为什么我Crm.Objects.Segmentation成为Crm.Data.Segmentation?何改回来?

UPDATE2 我认为问题出在我的数据上下文中。数据上下文有一个名称空间Crm.Data。我的实体在Crm.Objects中。然后我使用4.0.0 WCF一切都很好,但然后我切换到CTP2我的实体获取Crm.Data命名空间,而不是一个正确的Crm.Objects

回答

0

我想说,你引用另一个Segmentation类的实现比服务的。检查出的Segmentation命名空间中的CreateQuery<>()呼叫和Segmentation类的服务的命名空间。

+0

我有我的解决方案有3个项目:1.客户端应用程序2.实体对象项目3个网站与WCF服务项目。所以1和3对2个项目有相同的参考。我相信我在这两个项目中都使用了相同的参考。 – DolceVita 2011-06-16 13:18:13

+0

我也开始更新WCF服务CTP2 – DolceVita 2011-06-16 13:22:35

+0

上面的代码是从您的客户端应用程序后,出现此错误。它可能会将分段解析为Entity Objects项目中的一个,或者由WCF代理生成的一个。 – 2011-06-16 13:22:42

0

好吧,我觉得这是一个新的WCF CTP2的错误。然后我加回了System.Data.Services 4.0.0引用我在我的数据服务中得到了正确的命名空间。但后来我使用v4.99.2.0我在我的ds中得到了错误的命名空间。

+0

有一刻。我认为你的理由是在我的数据上下文中。数据上下文有一个名称空间Crm.Data。我的实体在Crm.Objects中。然后我用4.0.0 WCF一切都很好,但后来我改用CTP2我的实体获得Crm.Data命名空间,而不是一个正确的Crm.Objects ... – DolceVita 2011-06-17 07:28:09

0

我也曾有过类似的问题,不知道它是否会解决你的。

我必须做的是覆盖“的createDataSource”的方法,关闭代理创建在svc.cs文件。

下面的代码:

protected override DataServiceContext CreateDataSource() 
    { 
     var db = base.CreateDataSource(); 
     db.Configuration.ProxyCreationEnabled = false; 

     return db; 
    } 
4

你有没有尝试执行代表为DataServiceContext.ResolveNameDataServiceContext.ResolveType?这两个代表(如果提供的话)可用于修正odata名称空间+名称与客户端上序列化和反序列化的类型之间的映射。

下面是一个简单的例子:

internal class CustomDataServiceContext : DataServiceContext 
{ 
    public CustomDataServiceContext(Uri serviceRoot) 
    : base(serviceRoot, DataServiceProtocolVersion.V3) 
    { 
     this.ResolveName = ResolveNameFromType; 
     this.ResolveType = ResolveTypeFromName; 
    } 

    protected string ResolveNameFromType(Type clientType) 
    { 
     if (clientType.Namespace.Equals("ODataClient.MSProducts", StringComparison.Ordinal)) 
     { 
      return string.Concat("ODataService.Models.", clientType.Name); 
     } 
     return clientType.FullName; 
    } 

    protected Type ResolveTypeFromName(string typeName) 
    { 
     if (typeName.StartsWith("ODataService.Models", StringComparison.Ordinal)) 
     { 
      return this.GetType().Assembly.GetType(string.Concat("ODataClient.MSProducts", typeName.Substring(19)), false); 
     } 
     return null; 
    } 
} 

我不得不这样做(但我做到了灵活的,而不是硬编码),为了使我的实体类在WCF数据服务客户端工作;

但是,即使这样做之后,我有这个错误:

System.InvalidOperationException:有是客户端和服务之间的类型不匹配。类型WorkItem'不是一个实体类型,但响应负载中的类型表示一个实体类型。请确保客户端上定义的类型与服务的数据模型匹配,或者更新客户端上的服务引用。

我发现了两个补丁,为了这个工作:

  1. 添加[DataServiceKey("Id")]属性实体类。 或
  2. 重命名〜Id属性,使之与ID

结束我想通了,#2硬盘的方式 - 看反编译IL(这是WCF数据服务5.2.0)。审查ClientEdmModelClientTypeUtil后,我在ClientTypeUtil过这个方法来:

private static ClientTypeUtil.KeyKind IsKeyProperty(PropertyInfo propertyInfo, DataServiceKeyAttribute dataServiceKeyAttribute) 
{ 
    string name1 = propertyInfo.Name; 
    ClientTypeUtil.KeyKind keyKind = ClientTypeUtil.KeyKind.NotKey; 
    if (dataServiceKeyAttribute != null && dataServiceKeyAttribute.KeyNames.Contains(name1)) 
    keyKind = ClientTypeUtil.KeyKind.AttributedKey; 
    else if (name1.EndsWith("ID", StringComparison.Ordinal)) 
    { 
    string name2 = propertyInfo.DeclaringType.Name; 
    if (name1.Length == name2.Length + 2 && name1.StartsWith(name2, StringComparison.Ordinal)) 
     keyKind = ClientTypeUtil.KeyKind.TypeNameId; 
    else if (2 == name1.Length) 
     keyKind = ClientTypeUtil.KeyKind.Id; 
    } 
    return keyKind; 
} 

就这么name1.EndsWith("ID"上使用WCF数据服务的客户端你波苏斯时是关键。

希望有所帮助。

0

在同样的错误消息,刚刚来到,并固定在我的结束。事实证明,我正在混淆我的服务和客户端之间的程序集。一个使用Microsoft.Data.Services,另一个使用System.Data.Services。