WCF双向序列化失败

时间:2010-06-14 08:21:47

标签: wcf linq-to-sql serialization bidirectional

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

[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);  

2 个答案:

答案 0 :(得分:0)

L2ST4会帮助你。

我引用...

“LINQ to SQL支持开箱即用的基本DataContract序列化。这个基本的序列化没有机制告诉它关联的哪一端是所有者阻止序列化陷入循环因此LINQ to SQL只能序列化关系的一面。“

答案 1 :(得分:0)

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