2011-05-20 123 views
4

我一直在尋找答案以下問題幾天,迄今沒有任何運氣,任何幫助,非常感謝。WCF反序列化失去子集合

免責聲明:WCF和EntityFramework是新的概念給我,但.NET,c#,Web服務,對象關係映射概念當然不是。

我通過使用WCF服務的客戶端應用程序繼承了一個應用程序,以檢索並保存包含與「CaseNotesLog」對象的一對多關係的「Matter」對象。

客戶端可以使用0,1或許多子CaseNotesLog對象成功檢索某些Matters,它也可以成功地將具有添加,更新或刪除的CaseNotesLog對象的事件保存回去。

到目前爲止很好,但似乎有一組問題,與兒童CaseNotesLog對象可以成功讀取,但即使他們根本沒有被改變,但不能被保存。

從本質上看,當保存Matter對象失去了ChildNotesLog條目時,它看起來像WCF上的反序列化過程。

澄清:

    1. 的事情記錄在數據庫中1個CaseNotesLog子記錄,
    2. 在服務器上,這是順利地轉化爲的EntityFramework物質對象與孩子CaseNotesLog對象
    3. 這是通過WCF服務成功序列化/反序列化的,並正確使用客戶端上的子CaseNotesLog填充Matter對象。
  1. 保存
    1. 客戶端此事與孩子CaseNotesLog對象對象「葉子」的客戶端應用程序。
    2. 這是序列化,以通過WCF服務傳回服務器。
    3. 查看跟蹤日誌記錄此序列化包含孩子CaseNotesLog。
    4. 此對象在服務器端反序列化
    5. 通過將追蹤語句添加到實體框架Matter對象中的Setter代碼中,我可以觀察到CaseNotesLog子代被正確放置在父Matter中。
    6. 但只要吸氣功能被稱爲集合爲空

它彷彿RelationshipManager收集被重置其他地方。

最終的結果是,具有子CaseNotesLog對象的Matter對象將我的代碼留在客戶端,但它看起來像是在我檢查對象上的狀態時正確地序列化/反序列化服務器端的子記錄已經消失。

檢查我爲entityframework類添加了一些代碼,以保持子集合應該有多大的獨立計數。在設置CaseNotesLog集合時,它在Set操作期間設置爲1,並且在Get期間檢索CaseNotesLog集合時,即使集合已被清空,它仍然爲1。

若要添加到混淆 *這不適用於所有事項,有些似乎工作其他人不要 *這似乎不適用於所有類型的子對象,其他集似乎工作。

WCF服務,除其它方法,可以實現以下:

public class MattersService : IMattersService 
{ 

    ... 
    public Matter ReadMatter(int matterID) 
    { 
     using (var repo = new MatterRepository()) 
     { 
      try 
      { 
       return repo.ReadMatter(matterID); 
      } 
      catch (Exception ex) 
      { 
       Logger.Write(ex, "Error", 0); 
       throw; 
      } 
     } 
    } 
    ... 
    public void SaveMatter(Matter matter) 
    { 
     Trace.WriteLine(matter.CaseNotesLogs.Count); 
     using (var repo = new MatterRepository()) 
     { 
      try 
      { 
       repo.SaveMatter(matter); 
      } 
      catch (Exception ex) 
      { 
       Logger.Write(ex, "Error", 0); 
       throw; 
      } 
     } 
    } 
    ... 
} 

的物質是一個的EntityFramework生成的類:

/// <summary> 
/// No Metadata Documentation available. 
/// </summary> 
[EdmEntityTypeAttribute(NamespaceName="EDDSolutionsLtd.Services.Data", Name="Matter")] 
[Serializable()] 
[DataContractAttribute(IsReference=true)] 
public partial class Matter : EntityObject 
{ 
    ... 
    /// <summary> 
    /// No Metadata Documentation available. 
    /// </summary> 
    [XmlIgnoreAttribute()] 
    [SoapIgnoreAttribute()] 
    [DataMemberAttribute()] 
    [EdmRelationshipNavigationPropertyAttribute("EDDSolutionsLtd.Services.Data", "MatterCaseNotesLog", "CaseNotesLog")] 
    public EntityCollection<CaseNotesLog> CaseNotesLogs 
    { 
     get 
     { 
      return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<CaseNotesLog>("EDDSolutionsLtd.Services.Data.MatterCaseNotesLog", "CaseNotesLog"); 
     } 
     set 
     { 
      if ((value != null)) 
      { 
       ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<CaseNotesLog>("EDDSolutionsLtd.Services.Data.MatterCaseNotesLog", "CaseNotesLog", value); 
      } 
     } 
    } 
    ... 
} 

[ServiceContract] 
public interface IMattersService 
{ 
    ... 
    [OperationContract] 
    Matter ReadMatter(int matterID); 
    ... 
    [OperationContract] 
    void SaveMatter(Matter matter); 
    ... 
    } 
} 

它執行如下

損壞的版本我添加了一些日誌記錄到:

public int CheckCaseNotesLogsCount { get; set; } 
public EntityCollection<CaseNotesLog> CheckCaseNotesLogs { get; set; } 
/// <summary> 
/// No Metadata Documentation available. 
/// </summary> 
[XmlIgnoreAttribute()] 
[SoapIgnoreAttribute()] 
[DataMemberAttribute()] 
[EdmRelationshipNavigationPropertyAttribute("EDDSolutionsLtd.Services.Data", "MatterCaseNotesLog", "CaseNotesLog")] 
public EntityCollection<CaseNotesLog> CaseNotesLogs 
{ 
    get 
    { 
     if (CheckCaseNotesLogs != null) 
     { 
      Trace.WriteLine("GET ACTUAL CheckCaseNotesLogs[" + CheckCaseNotesLogs.Count + "]"); 
     } 
     Trace.WriteLine("GET ACTUAL CheckCaseNotesLogsCount[" + CheckCaseNotesLogsCount + "]"); 
     StackTrace st = new StackTrace(); 
     int i = ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<CaseNotesLog>("EDDSolutionsLtd.Services.Data.MatterCaseNotesLog", "CaseNotesLog").Count; 
     Trace.WriteLine("GET ACTUAL value[" + i + "]"); 
     Trace.WriteLine(st.ToString()); 
     return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<CaseNotesLog>("EDDSolutionsLtd.Services.Data.MatterCaseNotesLog", "CaseNotesLog"); 
    } 
    set 
    { 
     if ((value != null)) 
     { 
      CheckCaseNotesLogs = value; 
      CheckCaseNotesLogsCount = value.Count; 
      Trace.WriteLine("SET ACTUAL value[" + value.Count + "]"); 
      ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<CaseNotesLog>("EDDSolutionsLtd.Services.Data.MatterCaseNotesLog", "CaseNotesLog", value); 
      Trace.WriteLine("SET ACTUAL Property value[" + this.CaseNotesLogs.Count + "]"); 
     } 
     else 
     { 
      Trace.WriteLine("SET NULL Value"); 
     } 
    } 
} 

這是由Wcf服務收到的Soap消息的片段,顯示孩子CaseNotesLog記錄存在。

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent"> 

    <System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system"> 

    <EventID>0</EventID> 
    <Type>3</Type> 
    <SubType Name="Information">0</SubType> 
    <Level>8</Level> 
    <TimeCreated SystemTime="2011-05-19T22:49:34.7968750Z" /> 
    <Source Name="System.ServiceModel.MessageLogging" /> 
    <Correlation ActivityID="{fa25d214-04e9-4b16-8ae8-3de7b9a12bc6}" /> 
    <Execution ProcessName="WebDev.WebServer40" ProcessID="2332" ThreadID="13" /> 
    <Channel /> 
    <Computer>EDD-MERCURY</Computer> 
    </System> 
    <ApplicationData> 
    <TraceData> 
     <DataItem> 
     <MessageLogTraceRecord Time="2011-05-19T23:49:34.7812500+01:00" 
     Source="ServiceLevelReceiveRequest" 
     Type="System.ServiceModel.Channels.BufferedMessage" 
      xmlns="http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace"> 

      <HttpRequest> 
      <Method>POST</Method> 
      <QueryString></QueryString> 
      <WebHeaders> 
       <Content-Length>142631</Content-Length> 
       <Content-Type>application/soap+xml; 
       charset=utf-8</Content-Type> 
       <Expect>100-continue</Expect> 
       <Host>localhost:58080</Host> 
       <VsDebuggerCausalityData> 
       uIDPo7kHl/h9zQNAkghvTvB5/u8AAAAAuoDOged1MUm+UmudC0H6u3k/74R6jUpIn/o2sS4KNxYACQAA</VsDebuggerCausalityData> 
      </WebHeaders> 
      </HttpRequest> 
      <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" 
      xmlns:a="http://www.w3.org/2005/08/addressing"> 
      <s:Header> 
       <a:Action s:mustUnderstand="1"> 
       http://tempuri.org/IMattersService/SaveMatter</a:Action> 
       <a:MessageID> 
       urn:uuid:f1d751a7-1012-4268-b7da-87a12cf6d14f</a:MessageID> 
       <ActivityId CorrelationId="4f53460f-8880-4b6e-aa66-557fa90d4ae3" 
       xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics"> 
       fa25d214-04e9-4b16-8ae8-3de7b9a12bc6</ActivityId> 
       <a:ReplyTo> 
       <a:Address> 
       http://www.w3.org/2005/08/addressing/anonymous</a:Address> 
       </a:ReplyTo> 
       <a:To s:mustUnderstand="1"> 
       http://localhost:58080/MattersService.svc</a:To> 
      </s:Header> 
      <s:Body> 
       <SaveMatter xmlns="http://tempuri.org/"> 
       <matter z:Id="i1" 
       xmlns:b="http://schemas.datacontract.org/2004/07/EDDSolutionsLtd.Services.Data" 
       xmlns:i="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/"> 

        <EntityKey z:Id="i2" 
         xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses" 
        xmlns:c="http://schemas.datacontract.org/2004/07/System.Data"> 

        <c:EntityContainerName> 
        EDDSolutionsLtdEntities</c:EntityContainerName> 
        <c:EntityKeyValues> 
         <c:EntityKeyMember> 
         <c:Key>ID</c:Key> 
         <c:Value i:type="d:int" 
         xmlns:d="http://www.w3.org/2001/XMLSchema"> 
         180</c:Value> 
         </c:EntityKeyMember> 
        </c:EntityKeyValues> 
        <c:EntitySetName>Matters</c:EntitySetName> 
        </EntityKey> 
        <b:AllRecordsReceivedDate i:nil="true"> 
        </b:AllRecordsReceivedDate> 
        <b:BeginClaimDate i:nil="true"> 
        </b:BeginClaimDate> 

        ... 

        <b:CaseEmailLogs></b:CaseEmailLogs> 
        <b:CaseFileLogs></b:CaseFileLogs> 
        <b:CaseNotesLogs> 
        <b:CaseNotesLog z:Id="i3"> 
         <EntityKey z:Id="i4" 
          xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses" 
         xmlns:c="http://schemas.datacontract.org/2004/07/System.Data"> 

         <c:EntityContainerName> 
         EDDSolutionsLtdEntities</c:EntityContainerName> 
         <c:EntityKeyValues> 
          <c:EntityKeyMember> 
          <c:Key>ID</c:Key> 
          <c:Value i:type="d:int" 
          xmlns:d="http://www.w3.org/2001/XMLSchema"> 
          281</c:Value> 
          </c:EntityKeyMember> 
         </c:EntityKeyValues> 
         <c:EntitySetName> 
         CaseNotesLogs</c:EntitySetName> 
         </EntityKey> 
         <b:ActivityDate> 
         2011-05-18T00:00:00</b:ActivityDate> 
         <b:Body i:nil="true"></b:Body> 
         <b:Comment>3</b:Comment> 
         <b:ContactID>608</b:ContactID> 
         <b:CreatedBy>mminns</b:CreatedBy> 
         <b:CreatedOn> 
         2011-05-19T15:25:03.923</b:CreatedOn> 
         <b:ID>281</b:ID> 
         <b:MatterId>180</b:MatterId> 
         <b:ModifiedBy>mminns</b:ModifiedBy> 
         <b:ModifiedOn> 
         2011-05-19T15:25:03.923</b:ModifiedOn> 
         <b:OriginalContactID>0</b:OriginalContactID> 
         <b:Outcome>Unknown</b:Outcome> 
         <b:Subject>1</b:Subject> 
        </b:CaseNotesLog> 
        </b:CaseNotesLogs> 

        ... 

       </matter> 
       </SaveMatter> 
      </s:Body> 
      </s:Envelope> 
     </MessageLogTraceRecord> 
     </DataItem> 
    </TraceData> 
    </ApplicationData> 
</E2ETraceEvent>     
+0

道歉,因爲這不是一個答案,但我不能發表評論OP詢問一個問題。我假設你堅持這到一個SQL Server數據庫;你能夠將SQL Profiler附加到它,以查看在保存/獲取時究竟是從web服務器到數據庫發送了什麼?數據庫可能因某種原因刪除子記錄(觸發插入/更新或存儲過程)。這應該有助於確定問題是由數據庫還是由EF引起的。 – 2011-06-07 18:51:42

回答

0

你可以標記爲數據契約這個屬性:System.Runtime.Serialization.DataContractAttribute(IsReference =真)]