//------------------------------------------------------------------------------
// <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;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.ServiceModel;
namespace SchoolSample.EntityModel
{
[DataContract(IsReference = true)]
[KnownType(typeof(Course))]
[KnownType(typeof(Student))]
public partial class Enrollment: IObjectWithChangeTracker, INotifyPropertyChanged
{
#region Primitive Properties
[DataMember]
public int EnrollmentId
{
get { return _enrollmentId; }
set
{
if (_enrollmentId != value)
{
if (ChangeTracker.ChangeTrackingEnabled && ChangeTracker.State != ObjectState.Added)
{
throw new InvalidOperationException("The property 'EnrollmentId' 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.");
}
PropertySetterEntry("EnrollmentId");
_enrollmentId = value;
PropertySetterExit("EnrollmentId", value);
OnPropertyChanged("EnrollmentId");
}
}
}
private int _enrollmentId;
[DataMember]
[Display(Name="Student", Description="student")]
public int StudentId
{
get { return _studentId; }
set
{
if (_studentId != value)
{
ChangeTracker.RecordOriginalValue("StudentId", _studentId);
if (!IsDeserializing)
{
if (Student != null && Student.PersonId != value)
{
Student = null;
}
}
PropertySetterEntry("StudentId");
_studentId = value;
PropertySetterExit("StudentId", value);
OnPropertyChanged("StudentId");
}
}
}
private int _studentId;
[DataMember]
[Display(Name="Course", Description="course")]
public int CourseId
{
get { return _courseId; }
set
{
if (_courseId != value)
{
ChangeTracker.RecordOriginalValue("CourseId", _courseId);
if (!IsDeserializing)
{
if (Course != null && Course.CourseId != value)
{
Course = null;
}
}
PropertySetterEntry("CourseId");
_courseId = value;
PropertySetterExit("CourseId", value);
OnPropertyChanged("CourseId");
}
}
}
private int _courseId;
[DataMember]
[Display(Name="Tuition Paid", Description="whether tuition is paid or not")]
public bool Paid
{
get { return _paid; }
set
{
if (_paid != value)
{
ChangeTracker.RecordOriginalValue("Paid", _paid);
PropertySetterEntry("Paid");
_paid = value;
PropertySetterExit("Paid", value);
OnPropertyChanged("Paid");
}
}
}
private bool _paid;
[DataMember]
public byte[] Version
{
get { return _version; }
set
{
if (_version != value)
{
ChangeTracker.RecordOriginalValue("Version", _version);
PropertySetterEntry("Version");
_version = value;
PropertySetterExit("Version", value);
OnPropertyChanged("Version");
}
}
}
private byte[] _version;
#endregion
#region Navigation Properties
[DataMember]
public Course Course
{
get { return _course; }
set
{
if (!ReferenceEquals(_course, value))
{
var previousValue = _course;
PropertySetterEntry("Course");
_course = value;
PropertySetterExit("Course", value);
FixupCourse(previousValue);
OnNavigationPropertyChanged("Course");
}
}
}
private Course _course;
[DataMember]
public Student Student
{
get { return _student; }
set
{
if (!ReferenceEquals(_student, value))
{
var previousValue = _student;
PropertySetterEntry("Student");
_student = value;
PropertySetterExit("Student", value);
FixupStudent(previousValue);
OnNavigationPropertyChanged("Student");
}
}
}
private Student _student;
#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.SetParentObject(this);
_changeTracker.ObjectStateChanging += HandleObjectStateChanging;
_changeTracker.ObjectStateChanged += HandleObjectStateChanged;
_changeTracker.UpdateHasChanges += HandleUpdateHasChanges;
}
return _changeTracker;
}
set
{
if(_changeTracker != null)
{
_changeTracker.ObjectStateChanging -= HandleObjectStateChanging;
_changeTracker.ObjectStateChanged -= HandleObjectStateChanged;
_changeTracker.UpdateHasChanges -= HandleUpdateHasChanges;
}
_changeTracker = value;
_changeTracker.SetParentObject(this);
if(_changeTracker != null)
{
_changeTracker.ObjectStateChanging += HandleObjectStateChanging;
_changeTracker.ObjectStateChanged += HandleObjectStateChanged;
_changeTracker.UpdateHasChanges += HandleUpdateHasChanges;
}
}
}
private void HandleObjectStateChanging(object sender, ObjectStateChangingEventArgs e)
{
if (e.NewState == ObjectState.Deleted)
{
ClearNavigationProperties();
}
}
private void HandleObjectStateChanged(object sender, ObjectStateChangedEventArgs e)
{
#if (SILVERLIGHT || WPF)
// update HasChanges property
HasChanges = (ChangeTracker.State == ObjectState.Added) ||
(ChangeTracker.ChangeTrackingEnabled &&
(ChangeTracker.State != ObjectState.Unchanged ||
ChangeTracker.ObjectsAddedToCollectionProperties.Count != 0 ||
ChangeTracker.ObjectsRemovedFromCollectionProperties.Count != 0));
#endif
}
private void HandleUpdateHasChanges(object sender, EventArgs e)
{
#if (SILVERLIGHT || WPF)
// update HasChanges property
HasChanges = (ChangeTracker.State == ObjectState.Added) ||
(ChangeTracker.ChangeTrackingEnabled &&
(ChangeTracker.State != ObjectState.Unchanged ||
ChangeTracker.ObjectsAddedToCollectionProperties.Count != 0 ||
ChangeTracker.ObjectsRemovedFromCollectionProperties.Count != 0));
#endif
}
// 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 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()
{
Course = null;
Student = null;
}
#endregion
#region Validation and Helper Method
/// <summary>
/// Loops through all related data annotation attributes as well as all related
/// custom validation actions for the specified property name. If propertyName
/// is String.Empty/null, the validation is on the entity level.
/// </summary>
/// <param name="propertyName">Propery name or String.Empty/null for top-level errors</param>
/// <param name="value">New value that needs to be validated for the specified property</param>
public virtual void Validate(string propertyName, object value)
{
// process Data Annotation Attributes
var validationResults = new Collection<ValidationResult>();
if (string.IsNullOrEmpty(propertyName))
{
// this is top-level validation
ValidationContext context = new ValidationContext(this, null, null);
Validator.TryValidateObject(this, context, validationResults, true);
}
else
{
PropertyInfo property = GetType().GetProperty(propertyName);
if (property != null)
{
// this is validation for each property
ValidationContext context = new ValidationContext(this, null, null) { MemberName = propertyName };
Validator.TryValidateProperty(value, context, validationResults);
}
}
if (validationResults.Count != 0)
{
#if (SILVERLIGHT || WPF)
foreach (ValidationResult error in validationResults)
{
if (error.MemberNames.Count() == 0)
{
// this is top-level validation error
AddError(string.Empty, error);
}
else
{
foreach (string memberName in error.MemberNames)
{
AddError(memberName, error);
}
}
}
#else
FaultReason faultReason = new FaultReason(validationResults.First().ErrorMessage);
throw new FaultException(faultReason);
#endif
}
// next, process custom validation actions
if (ValidationActions.Count == 0) InitializeValidationSettings();
if (string.IsNullOrEmpty(propertyName))
{
// loop through all properties and call its list of validation actions
foreach (string memberName in ValidationActions.Keys.ToList())
{
List<Action<object>> actions = ValidationActions[memberName];
if (string.IsNullOrEmpty(memberName))
{
// this is top-level validation
actions.ForEach(action => action(this));
}
else
{
// this is validation for each property
object memberValue = GetType().GetProperty(memberName).GetValue(this, null);
actions.ForEach(action => action(memberValue));
}
}
}
else
{
if (ValidationActions.ContainsKey(propertyName))
{
List<Action<object>> actions = ValidationActions[propertyName];
actions.ForEach(action => action(value));
}
}
}
#if SILVERLIGHT
/// <summary>
/// Client-side validation function to loop through all data annotation
/// attributes and all custom validation actions. If any validation fails,
/// this function will return false. Otherwise, true.
/// </summary>
/// <returns></returns>
public virtual bool TryValidate()
{
// clear known errors for all property names.
ClearErrors();
// process Data Annotation Attributes
ValidationContext context = new ValidationContext(this, null, null);
var validationResults = new Collection<ValidationResult>();
Validator.TryValidateObject(this, context, validationResults, true);
if (validationResults.Count != 0)
{
foreach (ValidationResult error in validationResults)
{
if (error.MemberNames.Count() == 0)
{
// this is top-level validation error
AddError(string.Empty, error);
}
else
{
foreach (string propertyName in error.MemberNames)
{
AddError(propertyName, error);
}
}
}
}
// next, process custom validation actions
if (ValidationActions.Count == 0) InitializeValidationSettings();
// loop through all properties and call its list of validation actions
foreach (string propertyName in ValidationActions.Keys.ToList())
{
List<Action<object>> actions = ValidationActions[propertyName];
if (string.IsNullOrEmpty(propertyName))
{
// this is top-level validation
actions.ForEach(action => action(this));
}
else
{
// this is validation for each property
object value = GetType().GetProperty(propertyName).GetValue(this, null);
actions.ForEach(action => action(value));
}
}
return !(((INotifyDataErrorInfo)this).HasErrors);
}
/// <summary>
/// Client-side validation function for propertyName.
/// If any validation fails, this function will return false.
/// Otherwise, true.
/// </summary>
/// <param name="propertyName"></param>
/// <returns></returns>
public bool TryValidate(string propertyName)
{
if (string.IsNullOrEmpty(propertyName))
{
return TryValidate();
}
PropertyInfo property = GetType().GetProperty(propertyName);
if (property == null)
{
throw new ArgumentException(propertyName + " does not exist.");
}
// clear known errors for the property name
ClearErrors(propertyName);
// get the value of propertyName
object value = GetType().GetProperty(propertyName).GetValue(this, null);
Validate(propertyName, value);
IEnumerable errors = ((INotifyDataErrorInfo)this).GetErrors(propertyName);
if (errors == null) return true;
int count = errors.Cast<object>().Count();
return count == 0;
}
/// <summary>
/// Client-side validation function to loop through the whole object
/// graph. If any validation fails, this function will return false.
/// Otherwise, true.
/// </summary>
/// <returns></returns>
public bool TryValidateObjectGraph()
{
bool validated = true;
var visitedGraph = new List<object>();
TryValidateObjectGraph(ref validated, ref visitedGraph);
return validated;
}
internal virtual void TryValidateObjectGraph(ref bool validated, ref List<object> visitedGraph)
{
// if already visited this object, just return
if (visitedGraph.Any(n => ReferenceEquals(n, this))) return;
if (!TryValidate()) validated = false;
visitedGraph.Add(this);
// call TryValidateObjectGraph() on all Navigation properties
TryValidateOnNavigationProperties(ref validated, ref visitedGraph);
}
internal virtual void TryValidateOnNavigationProperties(ref bool validated, ref List<object> visitedGraph)
{
if (Course != null)
{
Course.TryValidateObjectGraph(ref validated, ref visitedGraph);
}
if (Student != null)
{
Student.TryValidateObjectGraph(ref validated, ref visitedGraph);
}
}
#elif WPF
/// <summary>
/// Client-side validation function to loop through all data annotation
/// attributes and all custom validation actions. If any validation fails,
/// this function will return false. Otherwise, true.
/// </summary>
/// <returns></returns>
public virtual bool TryValidate()
{
// clear known errors for all property names.
ClearErrors();
// First, process Data Annotation Attributes
ValidationContext context = new ValidationContext(this, null, null);
var validationResults = new Collection<ValidationResult>();
Validator.TryValidateObject(this, context, validationResults, true);
if (validationResults.Count != 0)
{
foreach (ValidationResult error in validationResults)
{
if (error.MemberNames.Count() == 0)
{
// this is top-level validation error
AddError(string.Empty, error);
}
else
{
foreach (string propertyName in error.MemberNames)
{
AddError(propertyName, error);
}
}
}
}
// Next, process custom validation actions
if (ValidationActions.Count == 0) InitializeValidationSettings();
// loop through all properties and call its list of validation actions
foreach (string propertyName in ValidationActions.Keys.ToList())
{
List<Action<object>> actions = ValidationActions[propertyName];
if (string.IsNullOrEmpty(propertyName))
{
// this is top-level validation
actions.ForEach(action => action(this));
}
else
{
// this is validation for each property
object value = GetType().GetProperty(propertyName).GetValue(this, null);
actions.ForEach(action => action(value));
}
}
return (ValidationErrors.Count == 0);
}
/// <summary>
/// Client-side validation function for propertyName.
/// If any validation fails, this function will return false.
/// Otherwise, true.
/// </summary>
/// <param name="propertyName"></param>
/// <returns></returns>
public bool TryValidate(string propertyName)
{
if (string.IsNullOrEmpty(propertyName))
{
return TryValidate();
}
PropertyInfo property = GetType().GetProperty(propertyName);
if (property == null)
{
throw new ArgumentException(propertyName + " does not exist.");
}
// clear known errors for the property name
ClearErrors(propertyName);
// get the value of propertyName
object value = GetType().GetProperty(propertyName).GetValue(this, null);
Validate(propertyName, value);
return ValidationErrors.ContainsKey(propertyName);
}
/// <summary>
/// Client-side validation function to loop through the whole object
/// graph. If any validation fails, this function will return false.
/// Otherwise, true.
/// </summary>
/// <returns></returns>
public bool TryValidateObjectGraph()
{
bool validated = true;
var visitedGraph = new List<object>();
TryValidateObjectGraph(ref validated, ref visitedGraph);
return validated;
}
internal virtual void TryValidateObjectGraph(ref bool validated, ref List<object> visitedGraph)
{
// if already visited this object, just return
if (visitedGraph.Any(n => ReferenceEquals(n, this))) return;
if (!TryValidate()) validated = false;
visitedGraph.Add(this);
// call TryValidateObjectGraph() on all Navigation properties
TryValidateOnNavigationProperties(ref validated, ref visitedGraph);
}
internal virtual void TryValidateOnNavigationProperties(ref bool validated, ref List<object> visitedGraph)
{
if (Course != null)
{
Course.TryValidateObjectGraph(ref validated, ref visitedGraph);
}
if (Student != null)
{
Student.TryValidateObjectGraph(ref validated, ref visitedGraph);
}
}
#else
/// <summary>
/// Server-side validation function to loop through all data annotation
/// attributes and all custom validation actions. If any validation fails,
/// it will through an exception.
/// </summary>
public virtual void Validate()
{
// process Data Annotation Attributes
ValidationContext context = new ValidationContext(this, null, null);
var validationResults = new Collection<ValidationResult>();
Validator.TryValidateObject(this, context, validationResults, true);
if (validationResults.Count != 0)
{
ValidationResult error = validationResults.First();
if (error.MemberNames.Count() == 0)
{
// this is top-level validation error
FaultReason faultReason = new FaultReason(error.ErrorMessage);
throw new FaultException(faultReason);
}
else
{
string propertyName = error.MemberNames.First();
FaultReason faultReason = new FaultReason(propertyName + " : " + error.ErrorMessage);
throw new FaultException(faultReason);
}
}
// Next, process custom validation actions
if (ValidationActions.Count == 0) InitializeValidationSettings();
// loop through all properties and call its list of validation actions
foreach (string propertyName in ValidationActions.Keys.ToList())
{
List<Action<object>> actions = ValidationActions[propertyName];
if (string.IsNullOrEmpty(propertyName))
{
// this is top-level validation
actions.ForEach(action => action(this));
}
else
{
// this is validation for each property
object value = GetType().GetProperty(propertyName).GetValue(this, null);
actions.ForEach(action => action(value));
}
}
}
/// <summary>
/// Server-side validation function to loop through the whole object
/// graph. If any validation fails, it will through an exception.
/// </summary>
/// <returns></returns>
public void ValidateObjectGraph()
{
var visitedGraph = new List<object>();
ValidateObjectGraph(ref visitedGraph);
}
internal virtual void ValidateObjectGraph(ref List<object> visitedGraph)
{
// if already visited this object, just return
if (visitedGraph.Any(n => ReferenceEquals(n, this))) return;
Validate();
visitedGraph.Add(this);
// call ValidateObjectGraph() on all Navigation properties
ValidateOnNavigationProperties(ref visitedGraph);
}
internal virtual void ValidateOnNavigationProperties(ref List<object> visitedGraph)
{
if (Course != null)
{
Course.ValidateObjectGraph(ref visitedGraph);
}
if (Student != null)
{
Student.ValidateObjectGraph(ref visitedGraph);
}
}
#endif
partial void PropertySetterEntry(string propertyName);
partial void PropertySetterExit(string propertyName, object propertyValue);
partial void InitializeValidationSettings();
private Dictionary<string, List<Action<object>>> ValidationActions
{
get
{
if (_validationActions == null)
{
_validationActions = new Dictionary<string, List<Action<object>>>();
}
return _validationActions;
}
}
private Dictionary<string, List<Action<object>>> _validationActions;
/// <summary>
/// Add one validation action for the specified property name.
/// </summary>
/// <param name="propertyName">Propery name or String.Empty/null for top-level errors</param>
/// <param name="validationAction">Function to carry out a specific validation action</param>
private void AddPropertyValidationAction(string propertyName, Action<object> validationAction)
{
List<Action<object>> validationActionList;
if (!ValidationActions.ContainsKey(propertyName))
{
validationActionList = new List<Action<object>>();
ValidationActions.Add(propertyName, validationActionList);
}
else
validationActionList = ValidationActions[propertyName];
validationActionList.Add(validationAction);
}
#endregion
#region Association Fixup
private void FixupCourse(Course previousValue)
{
if (IsDeserializing)
{
return;
}
if (previousValue != null && previousValue.Enrollments.Contains(this))
{
previousValue.Enrollments.Remove(this);
}
if (Course != null)
{
if (!Course.Enrollments.Contains(this))
{
Course.Enrollments.Add(this);
}
CourseId = Course.CourseId;
}
if (ChangeTracker.ChangeTrackingEnabled)
{
if (ChangeTracker.OriginalValues.ContainsKey("Course")
&& (ChangeTracker.OriginalValues["Course"] == Course))
{
ChangeTracker.OriginalValues.Remove("Course");
}
else
{
ChangeTracker.RecordOriginalValue("Course", previousValue);
}
if (Course != null && !Course.ChangeTracker.ChangeTrackingEnabled)
{
Course.StartTracking();
}
}
}
private void FixupStudent(Student previousValue)
{
if (IsDeserializing)
{
return;
}
if (previousValue != null && previousValue.Enrollments.Contains(this))
{
previousValue.Enrollments.Remove(this);
}
if (Student != null)
{
if (!Student.Enrollments.Contains(this))
{
Student.Enrollments.Add(this);
}
StudentId = Student.PersonId;
}
if (ChangeTracker.ChangeTrackingEnabled)
{
if (ChangeTracker.OriginalValues.ContainsKey("Student")
&& (ChangeTracker.OriginalValues["Student"] == Student))
{
ChangeTracker.OriginalValues.Remove("Student");
}
else
{
ChangeTracker.RecordOriginalValue("Student", previousValue);
}
if (Student != null && !Student.ChangeTracker.ChangeTrackingEnabled)
{
Student.StartTracking();
}
}
}
#endregion
}
}