2011-06-16 45 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。