2010-06-14 35 views
0

我想利用一些关系型Linq-2-Sql生成的实体类的双向序列化。当使用Unidirectional选项时,一切正常,当我添加IsReferenceType = true时,对象无法通过tcp绑定传输。 示例代码: 实体类:WCF双向序列化失败

[Table(Name="dbo.Blocks")] 
    [DataContract()] 
    public partial class Block : INotifyPropertyChanging, INotifyPropertyChanged 
    { 

     private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty); 

     private long _ID; 

     private int _StatusID; 

     private string _Name; 

     private bool _IsWithControlPoints; 

     private long _DivisionID; 

     private string _SHAPE; 

     private EntitySet<BlockByWorkstation> _BlockByWorkstations; 

     private EntitySet<PlanningPointAppropriation> _PlanningPointAppropriations; 

     private EntitySet<Neighbor> _Neighbors; 

     private EntitySet<Neighbor> _Neighbors1; 

     private EntitySet<Task> _Tasks; 

     private EntitySet<PlanningPointByBlock> _PlanningPointByBlocks; 

     private EntitySet<ControlPointByBlock> _ControlPointByBlocks; 

     private EntityRef<Division> _Division; 

     private bool serializing; 

    #region Extensibility Method Definitions 
    partial void OnLoaded(); 
    partial void OnValidate(System.Data.Linq.ChangeAction action); 
    partial void OnCreated(); 
    partial void OnIDChanging(long value); 
    partial void OnIDChanged(); 
    partial void OnStatusIDChanging(int value); 
    partial void OnStatusIDChanged(); 
    partial void OnNameChanging(string value); 
    partial void OnNameChanged(); 
    partial void OnIsWithControlPointsChanging(bool value); 
    partial void OnIsWithControlPointsChanged(); 
    partial void OnDivisionIDChanging(long value); 
    partial void OnDivisionIDChanged(); 
    partial void OnSHAPEChanging(string value); 
    partial void OnSHAPEChanged(); 
    #endregion 

     public Block() 
     { 
      this.Initialize(); 
     } 

     [Column(Storage="_ID", AutoSync=AutoSync.OnInsert, DbType="BigInt NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)] 
     [DataMember(Order=1)] 
     public override long ID 
     { 
      get 
      { 
       return this._ID; 
      } 
      set 
      { 
       if ((this._ID != value)) 
       { 
        this.OnIDChanging(value); 
        this.SendPropertyChanging(); 
        this._ID = value; 
        this.SendPropertyChanged("ID"); 
        this.OnIDChanged(); 
       } 
      } 
     } 

     [Column(Storage="_StatusID", DbType="Int NOT NULL")] 
     [DataMember(Order=2)] 
     public int StatusID 
     { 
      get 
      { 
       return this._StatusID; 
      } 
      set 
      { 
       if ((this._StatusID != value)) 
       { 
        this.OnStatusIDChanging(value); 
        this.SendPropertyChanging(); 
        this._StatusID = value; 
        this.SendPropertyChanged("StatusID"); 
        this.OnStatusIDChanged(); 
       } 
      } 
     } 

     [Column(Storage="_Name", DbType="NVarChar(255)")] 
     [DataMember(Order=3)] 
     public string Name 
     { 
      get 
      { 
       return this._Name; 
      } 
      set 
      { 
       if ((this._Name != value)) 
       { 
        this.OnNameChanging(value); 
        this.SendPropertyChanging(); 
        this._Name = value; 
        this.SendPropertyChanged("Name"); 
        this.OnNameChanged(); 
       } 
      } 
     } 

     [Column(Storage="_IsWithControlPoints", DbType="Bit NOT NULL")] 
     [DataMember(Order=4)] 
     public bool IsWithControlPoints 
     { 
      get 
      { 
       return this._IsWithControlPoints; 
      } 
      set 
      { 
       if ((this._IsWithControlPoints != value)) 
       { 
        this.OnIsWithControlPointsChanging(value); 
        this.SendPropertyChanging(); 
        this._IsWithControlPoints = value; 
        this.SendPropertyChanged("IsWithControlPoints"); 
        this.OnIsWithControlPointsChanged(); 
       } 
      } 
     } 

     [Column(Storage="_DivisionID", DbType="BigInt NOT NULL")] 
     [DataMember(Order=5)] 
     public long DivisionID 
     { 
      get 
      { 
       return this._DivisionID; 
      } 
      set 
      { 
       if ((this._DivisionID != value)) 
       { 
        if (this._Division.HasLoadedOrAssignedValue) 
        { 
         throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); 
        } 
        this.OnDivisionIDChanging(value); 
        this.SendPropertyChanging(); 
        this._DivisionID = value; 
        this.SendPropertyChanged("DivisionID"); 
        this.OnDivisionIDChanged(); 
       } 
      } 
     } 

     [Column(Storage="_SHAPE", DbType="Text", UpdateCheck=UpdateCheck.Never)] 
     [DataMember(Order=6)] 
     public string SHAPE 
     { 
      get 
      { 
       return this._SHAPE; 
      } 
      set 
      { 
       if ((this._SHAPE != value)) 
       { 
        this.OnSHAPEChanging(value); 
        this.SendPropertyChanging(); 
        this._SHAPE = value; 
        this.SendPropertyChanged("SHAPE"); 
        this.OnSHAPEChanged(); 
       } 
      } 
     } 

     [Association(Name="Block_BlockByWorkstation", Storage="_BlockByWorkstations", ThisKey="ID", OtherKey="BlockID")] 
     [DataMember(Order=7, EmitDefaultValue=false)] 
     public EntitySet<BlockByWorkstation> BlockByWorkstations 
     { 
      get 
      { 
       if ((this.serializing 
          && (this._BlockByWorkstations.HasLoadedOrAssignedValues == false))) 
       { 
        return null; 
       } 
       return this._BlockByWorkstations; 
      } 
      set 
      { 
       this._BlockByWorkstations.Assign(value); 
      } 
     } 

     [Association(Name="Block_PlanningPointAppropriation", Storage="_PlanningPointAppropriations", ThisKey="ID", OtherKey="MasterBlockID")] 
     [DataMember(Order=8, EmitDefaultValue=false)] 
     public EntitySet<PlanningPointAppropriation> PlanningPointAppropriations 
     { 
      get 
      { 
       if ((this.serializing 
          && (this._PlanningPointAppropriations.HasLoadedOrAssignedValues == false))) 
       { 
        return null; 
       } 
       return this._PlanningPointAppropriations; 
      } 
      set 
      { 
       this._PlanningPointAppropriations.Assign(value); 
      } 
     } 

     [Association(Name="Block_Neighbor", Storage="_Neighbors", ThisKey="ID", OtherKey="FirstBlockID")] 
     [DataMember(Order=9, EmitDefaultValue=false)] 
     public EntitySet<Neighbor> Neighbors 
     { 
      get 
      { 
       if ((this.serializing 
          && (this._Neighbors.HasLoadedOrAssignedValues == false))) 
       { 
        return null; 
       } 
       return this._Neighbors; 
      } 
      set 
      { 
       this._Neighbors.Assign(value); 
      } 
     } 

     [Association(Name="Block_Neighbor1", Storage="_Neighbors1", ThisKey="ID", OtherKey="SecondBlockID")] 
     [DataMember(Order=10, EmitDefaultValue=false)] 
     public EntitySet<Neighbor> Neighbors1 
     { 
      get 
      { 
       if ((this.serializing 
          && (this._Neighbors1.HasLoadedOrAssignedValues == false))) 
       { 
        return null; 
       } 
       return this._Neighbors1; 
      } 
      set 
      { 
       this._Neighbors1.Assign(value); 
      } 
     } 

     [Association(Name="Block_Task", Storage="_Tasks", ThisKey="ID", OtherKey="BlockID")] 
     [DataMember(Order=11, EmitDefaultValue=false)] 
     public EntitySet<Task> Tasks 
     { 
      get 
      { 
       if ((this.serializing 
          && (this._Tasks.HasLoadedOrAssignedValues == false))) 
       { 
        return null; 
       } 
       return this._Tasks; 
      } 
      set 
      { 
       this._Tasks.Assign(value); 
      } 
     } 

     [Association(Name="Block_PlanningPointByBlock", Storage="_PlanningPointByBlocks", ThisKey="ID", OtherKey="BlockID")] 
     [DataMember(Order=12, EmitDefaultValue=false)] 
     public EntitySet<PlanningPointByBlock> PlanningPointByBlocks 
     { 
      get 
      { 
       if ((this.serializing 
          && (this._PlanningPointByBlocks.HasLoadedOrAssignedValues == false))) 
       { 
        return null; 
       } 
       return this._PlanningPointByBlocks; 
      } 
      set 
      { 
       this._PlanningPointByBlocks.Assign(value); 
      } 
     } 

     [Association(Name="Block_ControlPointByBlock", Storage="_ControlPointByBlocks", ThisKey="ID", OtherKey="BlockID")] 
     [DataMember(Order=13, EmitDefaultValue=false)] 
     public EntitySet<ControlPointByBlock> ControlPointByBlocks 
     { 
      get 
      { 
       if ((this.serializing 
          && (this._ControlPointByBlocks.HasLoadedOrAssignedValues == false))) 
       { 
        return null; 
       } 
       return this._ControlPointByBlocks; 
      } 
      set 
      { 
       this._ControlPointByBlocks.Assign(value); 
      } 
     } 

     [Association(Name="Division_Block", Storage="_Division", ThisKey="DivisionID", OtherKey="ID", IsForeignKey=true, DeleteOnNull=true, DeleteRule="CASCADE")] 
     public Division Division 
     { 
      get 
      { 
       return this._Division.Entity; 
      } 
      set 
      { 
       Division previousValue = this._Division.Entity; 
       if (((previousValue != value) 
          || (this._Division.HasLoadedOrAssignedValue == false))) 
       { 
        this.SendPropertyChanging(); 
        if ((previousValue != null)) 
        { 
         this._Division.Entity = null; 
         previousValue.Blocks.Remove(this); 
        } 
        this._Division.Entity = value; 
        if ((value != null)) 
        { 
         value.Blocks.Add(this); 
         this._DivisionID = value.ID; 
        } 
        else 
        { 
         this._DivisionID = default(long); 
        } 
        this.SendPropertyChanged("Division"); 
       } 
      } 
     } 

     public event PropertyChangingEventHandler PropertyChanging; 

     public event PropertyChangedEventHandler PropertyChanged; 

     protected virtual void SendPropertyChanging() 
     { 
      if ((this.PropertyChanging != null)) 
      { 
       this.PropertyChanging(this, emptyChangingEventArgs); 
      } 
     } 

     protected virtual void SendPropertyChanged(String propertyName) 
     { 
      if ((this.PropertyChanged != null)) 
      { 
       this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 

     private void attach_BlockByWorkstations(BlockByWorkstation entity) 
     { 
      this.SendPropertyChanging(); 
      entity.Block = this; 
     } 

     private void detach_BlockByWorkstations(BlockByWorkstation entity) 
     { 
      this.SendPropertyChanging(); 
      entity.Block = null; 
     } 

     private void attach_PlanningPointAppropriations(PlanningPointAppropriation entity) 
     { 
      this.SendPropertyChanging(); 
      entity.Block = this; 
     } 

     private void detach_PlanningPointAppropriations(PlanningPointAppropriation entity) 
     { 
      this.SendPropertyChanging(); 
      entity.Block = null; 
     } 

     private void attach_Neighbors(Neighbor entity) 
     { 
      this.SendPropertyChanging(); 
      entity.FirstBlock = this; 
     } 

     private void detach_Neighbors(Neighbor entity) 
     { 
      this.SendPropertyChanging(); 
      entity.FirstBlock = null; 
     } 

     private void attach_Neighbors1(Neighbor entity) 
     { 
      this.SendPropertyChanging(); 
      entity.SecondBlock = this; 
     } 

     private void detach_Neighbors1(Neighbor entity) 
     { 
      this.SendPropertyChanging(); 
      entity.SecondBlock = null; 
     } 

     private void attach_Tasks(Task entity) 
     { 
      this.SendPropertyChanging(); 
      entity.Block = this; 
     } 

     private void detach_Tasks(Task entity) 
     { 
      this.SendPropertyChanging(); 
      entity.Block = null; 
     } 

     private void attach_PlanningPointByBlocks(PlanningPointByBlock entity) 
     { 
      this.SendPropertyChanging(); 
      entity.Block = this; 
     } 

     private void detach_PlanningPointByBlocks(PlanningPointByBlock entity) 
     { 
      this.SendPropertyChanging(); 
      entity.Block = null; 
     } 

     private void attach_ControlPointByBlocks(ControlPointByBlock entity) 
     { 
      this.SendPropertyChanging(); 
      entity.Block = this; 
     } 

     private void detach_ControlPointByBlocks(ControlPointByBlock entity) 
     { 
      this.SendPropertyChanging(); 
      entity.Block = null; 
     } 

     private void Initialize() 
     { 
      this._BlockByWorkstations = new EntitySet<BlockByWorkstation>(new Action<BlockByWorkstation>(this.attach_BlockByWorkstations), new Action<BlockByWorkstation>(this.detach_BlockByWorkstations)); 
      this._PlanningPointAppropriations = new EntitySet<PlanningPointAppropriation>(new Action<PlanningPointAppropriation>(this.attach_PlanningPointAppropriations), new Action<PlanningPointAppropriation>(this.detach_PlanningPointAppropriations)); 
      this._Neighbors = new EntitySet<Neighbor>(new Action<Neighbor>(this.attach_Neighbors), new Action<Neighbor>(this.detach_Neighbors)); 
      this._Neighbors1 = new EntitySet<Neighbor>(new Action<Neighbor>(this.attach_Neighbors1), new Action<Neighbor>(this.detach_Neighbors1)); 
      this._Tasks = new EntitySet<Task>(new Action<Task>(this.attach_Tasks), new Action<Task>(this.detach_Tasks)); 
      this._PlanningPointByBlocks = new EntitySet<PlanningPointByBlock>(new Action<PlanningPointByBlock>(this.attach_PlanningPointByBlocks), new Action<PlanningPointByBlock>(this.detach_PlanningPointByBlocks)); 
      this._ControlPointByBlocks = new EntitySet<ControlPointByBlock>(new Action<ControlPointByBlock>(this.attach_ControlPointByBlocks), new Action<ControlPointByBlock>(this.detach_ControlPointByBlocks)); 
      this._Division = default(EntityRef<Division>); 
      OnCreated(); 
     } 

     [OnDeserializing()] 
     [System.ComponentModel.EditorBrowsableAttribute(EditorBrowsableState.Never)] 
     public void OnDeserializing(StreamingContext context) 
     { 
      this.Initialize(); 
     } 

     [OnSerializing()] 
     [System.ComponentModel.EditorBrowsableAttribute(EditorBrowsableState.Never)] 
     public void OnSerializing(StreamingContext context) 
     { 
      this.serializing = true; 
     } 

     [OnSerialized()] 
     [System.ComponentModel.EditorBrowsableAttribute(EditorBrowsableState.Never)] 
     public void OnSerialized(StreamingContext context) 
     { 
      this.serializing = false; 
     } 
    } 

的App.config:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.web> 
    <compilation debug="true" /> 
    </system.web> 
    <!-- When deploying the service library project, the content of the config file must be added to the host's 
    app.config file. System.Configuration does not support config files for libraries. --> 
    <system.serviceModel> 
    <services> 
     <service behaviorConfiguration="debugging" 
     name="DBServicesLibrary.DBService">    
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="DBServicesLibrary.DBServiceBehavior"> 
      <!-- To avoid disclosing metadata information, 
      set the value below to false and remove the metadata endpoint above before deployment --> 
      <serviceMetadata httpGetEnabled="True"/> 

      <!-- To receive exception details in faults for debugging purposes, 
      set the value below to true. Set to false before deployment 
      to avoid disclosing exception information --> 
      <serviceDebug includeExceptionDetailInFaults="False" /> 
     </behavior> 
     <behavior name="debugging"> 
      <serviceDebug includeExceptionDetailInFaults="true"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 
</configuration> 

主机部分:

ServiceHost svh = new ServiceHost(typeof(DBService)); 
      svh.AddServiceEndpoint(
       typeof(DBServices.Contract.IDBService), 
       new NetTcpBinding(), 
       "net.tcp://localhost:8000"); 

客户端部分:

ChannelFactory<DBServices.Contract.IDBService> scf; 
      scf = new ChannelFactory<DBServices.Contract.IDBService>(new NetTcpBinding(),"net.tcp://localhost:8000"); 


      _serv = scf.CreateChannel(); 
      ((IContextChannel)_serv).OperationTimeout = new TimeSpan(0, 5, 0); 

回答

0

L2ST4会帮助你。

我引用...

“的LINQ to SQL支持基本DataContract序列开箱即用的。这个基本系列化没有机制来告诉它关联的结束是为了防止系列化业主被卡住在一个循环中,所以LINQ to SQL只会序列化关系的一端。“

+0

谢谢,我会试试这个 – 2010-06-15 06:50:36

+0

L2ST4只是将IsReference = True属性添加到每个生成的类中,不是吗? 我自己做过,并遇到同样的问题。 下载模板并应用后,问题依然存在。 – 2010-06-15 07:22:45

0

仅将IsReferenceType = true添加到DataContract属性是不够的。您还必须确保所有属性都具有DataMember属性。将序列化模式设置为单向时,它只会自动向一个方向添加DataMember属性。例如,它会自动将属性放在Group.Users上,但您必须自己将其添加到User.Group。我最近尝试手动添加IsReferenceType = true和DataMember,它的工作。

+0

感谢您的回复。 我遵循你的建议,但它也没有帮助。 在我的情况下,有一个叫做Block的对象和一个叫Task的对象。 关系是1->许多(一个块 - >许多任务)。 该块的任务属性序列化正常,但即使在手动添加上述属性后,该任务的Block属性也无法反序列化... – 2010-06-23 11:21:39