2012-01-04 14 views
2

State Trackerを維持するために、Ado.netセルフトラッキングエンティティジェネレータを使用して作成されたオブジェクト。オブジェクトはユーザ、トレーナーです。トレーナーはユーザーの子オブジェクトです。トレーナーで変更された情報は、変更された状態で変更されます。ユーザーオブジェクトは変更されません。私の要件は、親オブジェクトに親密にする必要がある子オブジェクトが変更されたときです。ObjectWithChangeTrackerを使用して親オブジェクトに子オブジェクトの変更を通知する方法

User.cs

//------------------------------------------------------------------------------ 
// <auto-generated> 
//  This code was generated from a template. 
// 
//  Changes to this file may cause incorrect behavior and will be lost if 
//  the code is regenerated. 
// </auto-generated> 
//------------------------------------------------------------------------------ 

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Collections.Specialized; 
using System.ComponentModel; 
using System.Globalization; 
using System.Runtime.Serialization; 

namespace ControlLibrary 
{ 
    [DataContract(IsReference = true)] 
    [KnownType(typeof(Trainer))] 
    public partial class User: IObjectWithChangeTracker, INotifyPropertyChanged 
    { 
     #region Primitive Properties 

     [DataMember] 
     public int UserId 
     { 
      get { return _userId; } 
      set 
      { 
       if (_userId != value) 
       { 
        if (ChangeTracker.ChangeTrackingEnabled && ChangeTracker.State != ObjectState.Added) 
        { 
         throw new InvalidOperationException("The property 'UserId' is part of the object's key and cannot be changed. Changes to key properties can only be made when the object is not being tracked or is in the Added state."); 
        } 
        _userId = value; 
        OnPropertyChanged("UserId"); 
       } 
      } 
     } 
     private int _userId; 

     [DataMember] 
     public string UserName 
     { 
      get { return _userName; } 
      set 
      { 
       if (_userName != value) 
       { 
        _userName = value; 
        OnPropertyChanged("UserName"); 
       } 
      } 
     } 
     private string _userName; 

     #endregion 
     #region Navigation Properties 

     [DataMember] 
     public Trainer Trainer 
     { 
      get { return _trainer; } 
      set 
      { 
       if (!ReferenceEquals(_trainer, value)) 
       { 
        var previousValue = _trainer; 
        _trainer = value; 
        FixupTrainer(previousValue); 
        OnNavigationPropertyChanged("Trainer"); 
       } 
      } 
     } 
     private Trainer _trainer; 

     #endregion 
     #region ChangeTracking 

     protected virtual void OnPropertyChanged(String propertyName) 
     { 
      if (ChangeTracker.State != ObjectState.Added && ChangeTracker.State != ObjectState.Deleted) 
      { 
       ChangeTracker.State = ObjectState.Modified; 
      } 
      if (_propertyChanged != null) 
      { 
       _propertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 

     protected virtual void OnNavigationPropertyChanged(String propertyName) 
     { 
      if (_propertyChanged != null) 
      { 
       _propertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 

     event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged{ add { _propertyChanged += value; } remove { _propertyChanged -= value; } } 
     private event PropertyChangedEventHandler _propertyChanged; 
     private ObjectChangeTracker _changeTracker; 

     [DataMember] 
     public ObjectChangeTracker ChangeTracker 
     { 
      get 
      { 
       if (_changeTracker == null) 
       { 
        _changeTracker = new ObjectChangeTracker(); 
        _changeTracker.ObjectStateChanging += HandleObjectStateChanging; 
       } 
       return _changeTracker; 
      } 
      set 
      { 
       if(_changeTracker != null) 
       { 
        _changeTracker.ObjectStateChanging -= HandleObjectStateChanging; 
       } 
       _changeTracker = value; 
       if(_changeTracker != null) 
       { 
        _changeTracker.ObjectStateChanging += HandleObjectStateChanging; 
       } 
      } 
     } 

     private void HandleObjectStateChanging(object sender, ObjectStateChangingEventArgs e) 
     { 
      if (e.NewState == ObjectState.Deleted) 
      { 
       ClearNavigationProperties(); 
      } 
     } 

     protected bool IsDeserializing { get; private set; } 

     [OnDeserializing] 
     public void OnDeserializingMethod(StreamingContext context) 
     { 
      IsDeserializing = true; 
     } 

     [OnDeserialized] 
     public void OnDeserializedMethod(StreamingContext context) 
     { 
      IsDeserializing = false; 
      ChangeTracker.ChangeTrackingEnabled = true; 
     } 

     protected virtual void ClearNavigationProperties() 
     { 
      Trainer = null; 
     } 

     #endregion 
     #region Association Fixup 

     private void FixupTrainer(Trainer previousValue) 
     { 
      // This is the principal end in an association that performs cascade deletes. 
      // Update the event listener to refer to the new dependent. 
      if (previousValue != null) 
      { 
       ChangeTracker.ObjectStateChanging -= previousValue.HandleCascadeDelete; 
      } 

      if (Trainer != null) 
      { 
       ChangeTracker.ObjectStateChanging += Trainer.HandleCascadeDelete; 
      } 

      if (IsDeserializing) 
      { 
       return; 
      } 

      if (previousValue != null && ReferenceEquals(previousValue.User, this)) 
      { 
       previousValue.User = null; 
      } 

      if (Trainer != null) 
      { 
       Trainer.User = this; 
      } 

      if (ChangeTracker.ChangeTrackingEnabled) 
      { 
       if (ChangeTracker.OriginalValues.ContainsKey("Trainer") 
        && (ChangeTracker.OriginalValues["Trainer"] == Trainer)) 
       { 
        ChangeTracker.OriginalValues.Remove("Trainer"); 
       } 
       else 
       { 
        ChangeTracker.RecordOriginalValue("Trainer", previousValue); 
        // This is the principal end of an identifying association, so the dependent must be deleted when the relationship is removed. 
        // If the current state of the dependent is Added, the relationship can be changed without causing the dependent to be deleted. 
        if (previousValue != null && previousValue.ChangeTracker.State != ObjectState.Added) 
        { 
         previousValue.MarkAsDeleted(); 
        } 
       } 
       if (Trainer != null && !Trainer.ChangeTracker.ChangeTrackingEnabled) 
       { 
        Trainer.StartTracking(); 
       } 
      } 
     } 

     #endregion 
    } 
} 

Trainer.csファイルは、あなたがこれを行うにはしたくない

//------------------------------------------------------------------------------ 
// <auto-generated> 
//  This code was generated from a template. 
// 
//  Changes to this file may cause incorrect behavior and will be lost if 
//  the code is regenerated. 
// </auto-generated> 
//------------------------------------------------------------------------------ 

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Collections.Specialized; 
using System.ComponentModel; 
using System.Globalization; 
using System.Runtime.Serialization; 

namespace ControlLibrary 
{ 
    [DataContract(IsReference = true)] 
    [KnownType(typeof(User))] 
    public partial class Trainer: IObjectWithChangeTracker, INotifyPropertyChanged 
    { 
     #region Primitive Properties 

     [DataMember] 
     public int TrainerId 
     { 
      get { return _trainerId; } 
      set 
      { 
       if (_trainerId != value) 
       { 
        if (ChangeTracker.ChangeTrackingEnabled && ChangeTracker.State != ObjectState.Added) 
        { 
         throw new InvalidOperationException("The property 'TrainerId' is part of the object's key and cannot be changed. Changes to key properties can only be made when the object is not being tracked or is in the Added state."); 
        } 
        if (!IsDeserializing) 
        { 
         if (User != null && User.UserId != value) 
         { 
          User = null; 
         } 
        } 
        _trainerId = value; 
        OnPropertyChanged("TrainerId"); 
       } 
      } 
     } 
     private int _trainerId; 

     [DataMember] 
     public int UserId 
     { 
      get { return _userId; } 
      set 
      { 
       if (_userId != value) 
       { 
        _userId = value; 
        OnPropertyChanged("UserId"); 
       } 
      } 
     } 
     private int _userId; 

     [DataMember] 
     public Nullable<bool> IsFloorTrainer 
     { 
      get { return _isFloorTrainer; } 
      set 
      { 
       if (_isFloorTrainer != value) 
       { 
        _isFloorTrainer = value; 
        OnPropertyChanged("IsFloorTrainer"); 
       } 
      } 
     } 
     private Nullable<bool> _isFloorTrainer; 

     #endregion 
     #region Navigation Properties 

     [DataMember] 
     public User User 
     { 
      get { return _user; } 
      set 
      { 
       if (!ReferenceEquals(_user, value)) 
       { 
        if (ChangeTracker.ChangeTrackingEnabled && ChangeTracker.State != ObjectState.Added && value != null) 
        { 
         // This the dependent end of an identifying relationship, so the principal end cannot be changed if it is already set, 
         // otherwise it can only be set to an entity with a primary key that is the same value as the dependent's foreign key. 
         if (TrainerId != value.UserId) 
         { 
          throw new InvalidOperationException("The principal end of an identifying relationship can only be changed when the dependent end is in the Added state."); 
         } 
        } 
        var previousValue = _user; 
        _user = value; 
        FixupUser(previousValue); 
        OnNavigationPropertyChanged("User"); 
       } 
      } 
     } 
     private User _user; 

     #endregion 
     #region ChangeTracking 

     protected virtual void OnPropertyChanged(String propertyName) 
     { 
      if (ChangeTracker.State != ObjectState.Added && ChangeTracker.State != ObjectState.Deleted) 
      { 
       ChangeTracker.State = ObjectState.Modified; 
      } 
      if (_propertyChanged != null) 
      { 
       _propertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 

     protected virtual void OnNavigationPropertyChanged(String propertyName) 
     { 
      if (_propertyChanged != null) 
      { 
       _propertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 

     event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged{ add { _propertyChanged += value; } remove { _propertyChanged -= value; } } 
     private event PropertyChangedEventHandler _propertyChanged; 
     private ObjectChangeTracker _changeTracker; 

     [DataMember] 
     public ObjectChangeTracker ChangeTracker 
     { 
      get 
      { 
       if (_changeTracker == null) 
       { 
        _changeTracker = new ObjectChangeTracker(); 
        _changeTracker.ObjectStateChanging += HandleObjectStateChanging; 
       } 
       return _changeTracker; 
      } 
      set 
      { 
       if(_changeTracker != null) 
       { 
        _changeTracker.ObjectStateChanging -= HandleObjectStateChanging; 
       } 
       _changeTracker = value; 
       if(_changeTracker != null) 
       { 
        _changeTracker.ObjectStateChanging += HandleObjectStateChanging; 
       } 
      } 
     } 

     private void HandleObjectStateChanging(object sender, ObjectStateChangingEventArgs e) 
     { 
      if (e.NewState == ObjectState.Deleted) 
      { 
       ClearNavigationProperties(); 
      } 
     } 

     protected bool IsDeserializing { get; private set; } 

     [OnDeserializing] 
     public void OnDeserializingMethod(StreamingContext context) 
     { 
      IsDeserializing = true; 
     } 

     [OnDeserialized] 
     public void OnDeserializedMethod(StreamingContext context) 
     { 
      IsDeserializing = false; 
      ChangeTracker.ChangeTrackingEnabled = true; 
     } 

     // This entity type is the dependent end in at least one association that performs cascade deletes. 
     // This event handler will process notifications that occur when the principal end is deleted. 
     internal void HandleCascadeDelete(object sender, ObjectStateChangingEventArgs e) 
     { 
      if (e.NewState == ObjectState.Deleted) 
      { 
       this.MarkAsDeleted(); 
      } 
     } 

     protected virtual void ClearNavigationProperties() 
     { 
      User = null; 
     } 

     #endregion 
     #region Association Fixup 

     private void FixupUser(User previousValue) 
     { 
      if (IsDeserializing) 
      { 
       return; 
      } 

      if (previousValue != null && ReferenceEquals(previousValue.Trainer, this)) 
      { 
       previousValue.Trainer = null; 
      } 

      if (User != null) 
      { 
       User.Trainer = this; 
       TrainerId = User.UserId; 
      } 

      if (ChangeTracker.ChangeTrackingEnabled) 
      { 
       if (ChangeTracker.OriginalValues.ContainsKey("User") 
        && (ChangeTracker.OriginalValues["User"] == User)) 
       { 
        ChangeTracker.OriginalValues.Remove("User"); 
       } 
       else 
       { 
        ChangeTracker.RecordOriginalValue("User", previousValue); 
       } 
       if (User != null && !User.ChangeTracker.ChangeTrackingEnabled) 
       { 
        User.StartTracking(); 
       } 
      } 
     } 

     #endregion 
    } 
} 
+0

イベントを追加するか、または親/子イベントを処理するために代理人またはAnonymousDelegateを作成することも見てください – MethodMan

+0

Ado.netセルフトラッキングエンティティジェネレータによって生成されるコードは、このリンクで使用できます[url = http: //www.fileserve.com/file/nUwkHra/ControlLibrary.rar][b]ファイル名:ControlLibrary.rarファイルサイズ:15.97 KB [/ b] [/ url] – VIJAY

+0

個人はあなたの.rarファイルをダウンロードしないでしょう。彼らの内部のファイアウォールとセキュリティは、コードが必要であり、あなたの質問に適用されます貼り付けます。ありがとう – MethodMan

答えて

0

です。より複雑なオブジェクトグラフがあり、オブジェクトのインスタンスが変更された場合、これは上にあるすべての親に伝播することを意味します。これはそれほど問題ではありません。しかし、永続化エンティティのためにObjectContextに変更を適用すると、FrameWorkはすべての親を更新します(ターゲットが親のChangeTrackerへの変更を伝播する場合) - ChangeTrackerは、FrameWorkが変更を検出するために使用するオブジェクトですデータベースへの照会の更新、挿入、または削除を行います)。

Entity Frameworkは、この種の「カスケード」情報をセルフトラッキングエンティティ自体には含めません。

類似の機能が必要でした。何かが下に変化した場合に「トップレベル」のオブジェクトを簡単に検出する。すべての基礎となるエンティティを確認するための再帰的メソッドを作成し、StateChangeTrackersを確認しました。注意:entity.ChangeTracker.Stateを参照するだけでなく、entity.ChangeTracker.AddedToCollectionPropertiesentity.ChangeTracker.RemovedFromCollectionPropertiesでも、エンティティがナビゲーションプロパティ(基本的には変更されている)に追加または削除されているかどうかを確認する必要があります。

また、すべてのエンティティに単純なEnum(クリーン、変更済み、追加済み、削除済みなど)を含めることもできます。また、エンティティと上の「親」のEnum変数を変更すると変更されます。この方法で、私があまりにも多く混乱しないChangeTrackerを妨害しないでください。

これが役に立ちます。

関連する問題