使用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
}
}
你是否有代码示例..也看看添加事件或创建一个委托或AnonymousDelegate来处理父/子事件 – MethodMan 2012-01-04 18:19:15
由Ado.net自我跟踪实体生成器生成的代码是可用的在这个链接[url = http: //www.fileserve.com/file/nUwkHra/ControlLibrary.rar] [b]文件名:ControlLibrary.rar文件大小:15.97 KB [/ url] – VIJAY 2012-01-04 18:30:58
个人不会下载你的.rar文件可能是由于他们的内部防火墙和安全性,所以粘贴什么代码是必要的,适用于你的问题。谢谢 – MethodMan 2012-01-04 18:34:28