internal void RollBack(EntityBase entityBase) { Replace(entityBase); }
/// <summary> /// Replaces core data from the specified field (FieldInfo) in entity. /// </summary> protected void ReplaceForFieldInfo(FieldInfo fi, EntityBase entity) { // if the field is a NuSoft Framework entity or entityList, then we need to take care to // preserve the currently existing entity and entityList instantiated objects as the consumer may // have reference to them (ie. data bound to a presentation control) if ((fi.FieldType.IsGenericType) && (fi.FieldType.GetGenericTypeDefinition().Equals(typeof(EntityList <>)))) { System.Collections.IList entityListSource = fi.GetValue(entity) as System.Collections.IList; System.Collections.IList entityListTarget = fi.GetValue(this) as System.Collections.IList; if ((entityListSource == null) && (entityListTarget != null)) { // un-lazy load the private member of the source so that the entityList items are visible... after loading the items, then the // "if ((entityList != null) && (entityListSource != null))" clause will be hit below, effectively adding the items to the already- // existing entityList instantiated object. string memberName = fi.Name; if (memberName.IndexOf('_') == 0) { string propertyName = memberName.Substring(1, 1).ToUpper() + memberName.Substring(2); PropertyInfo propertyInfo = this.GetType().GetProperty(propertyName); if (propertyInfo != null) { // we're not going to do anything with entityListForProperty... we just access it get the the entityList lazily-loaded. System.Collections.IList entityListForProperty = propertyInfo.GetValue(entity, null) as System.Collections.IList; entityListSource = fi.GetValue(entity) as System.Collections.IList; entityListTarget = fi.GetValue(this) as System.Collections.IList; } } } if ((entityListTarget != null) && (entityListSource != null)) { // todo:mjj move this section to entityList.Replace(entityList) for (int i = entityListTarget.Count - 1; i >= 0; i--) { EntityBase entityTarget = (EntityBase)entityListTarget[i]; EntityBase entitySource = (EntityBase)((ISearchable)entityListSource).GetEntityById(entityTarget.UniqueIdentifier); if (entityTarget.IsDeleted) { entityListTarget.Remove(entityTarget); } else if (entitySource != null) { entityTarget.Replace(entitySource); } else { entityListTarget.Remove(entityTarget); } } foreach (EntityBase entitySource in entityListSource) { EntityBase entityTarget = (EntityBase)((ISearchable)entityListTarget).GetEntityById(entitySource.UniqueIdentifier); if (entityTarget == null) { entityListTarget.Add(entitySource); } } } else if ((entityListSource != null) && (entityListTarget == null)) { SetFieldValueAndTriggerPropertyChangedEvent(this, fi, ((ICloneable)fi.GetValue(entity)).Clone()); } else { SetFieldValueAndTriggerPropertyChangedEvent(this, fi, fi.GetValue(entity)); } } else if (fi.FieldType.IsSubclassOf(typeof(EntityBase))) { EntityBase entityBaseTarget = fi.GetValue(this) as EntityBase; EntityBase entityBaseSource = fi.GetValue(entity) as EntityBase; if ((entityBaseSource == null) && (entityBaseTarget != null)) { // provoke source entity's corresponding property to get it lazily loaded string memberName = fi.Name; if (memberName.IndexOf('_') == 0) { string propertyName = memberName.Substring(1, 1).ToUpper() + memberName.Substring(2); PropertyInfo propertyInfo = this.GetType().GetProperty(propertyName); if (propertyInfo != null) { // we're not going to do anything with entityBase... we just access it to get it lazily-loaded. EntityBase entityBase = propertyInfo.GetValue(entity, null) as EntityBase; entityBaseSource = fi.GetValue(entity) as EntityBase; } } } if ((entityBaseTarget != null) && (entityBaseSource != null)) { if (entityBaseTarget.UniqueIdentifier == entityBaseSource.UniqueIdentifier) { entityBaseTarget.Replace(entityBaseSource); } else { SetFieldValueAndTriggerPropertyChangedEvent(this, fi, fi.GetValue(entity)); } } else if ((entityBaseSource != null) && (entityBaseTarget == null)) { SetFieldValueAndTriggerPropertyChangedEvent(this, fi, ((ICloneable)fi.GetValue(entity)).Clone()); } else { SetFieldValueAndTriggerPropertyChangedEvent(this, fi, fi.GetValue(entity)); } } else { SetFieldValueAndTriggerPropertyChangedEvent(this, fi, fi.GetValue(entity)); } }
/// <summary> /// Replaces data from the specified property (PropertyInfo) in entity. /// </summary> protected void ReplaceForPropertyInfo(PropertyInfo propertyInfo, EntityBase entity) { // If the setter method of the property is not public, then don't process it. This will exclude ID fields, for instance. if (propertyInfo.GetSetMethod(false) != null) { // if the property is a NuSoft Framework entity or entityList, then we need to take care to // preserve the currently existing entity and entityList instantiated objects as the consumer may // have reference to them (ie. data bound to a presentation control) // if the property is an entityList... if ((propertyInfo.PropertyType.IsGenericType) && (propertyInfo.PropertyType.GetGenericTypeDefinition().Equals(typeof(EntityList <>)))) { // Get the source object's private member that corresponds to the property (ie. the property backer). // If it's value is not null, then let's get the collection's members and merge them into the target's collection. // A null collection for the source does not mean that the target should then be null; it only means that the // source's collection was never lazily loaded. string propertyName = propertyInfo.Name; string memberName = "_" + propertyName.Substring(0, 1).ToLower() + propertyName.Substring(1); FieldInfo fieldInfo = this.GetType().GetField(memberName, BINDINGS_PRIVATE_INSTANCES); if ((fieldInfo != null) && ((fieldInfo.GetValue(entity) as System.Collections.IList) != null)) { // By virture of unique identifer... // - Exists in source collection, and exists in target collection, then merge to target collection // - Exists in source, but not is target, add to target. // - Doesn't exist in source, and doesn't exist in target, do nothing. // - Doesn't exist in source, but does in target, delete/remove from source. System.Collections.IList entityListSource = propertyInfo.GetValue(entity, null) as System.Collections.IList; System.Collections.IList entityListTarget = propertyInfo.GetValue(this, null) as System.Collections.IList; for (int i = entityListTarget.Count - 1; i >= 0; i--) { EntityBase entityTarget = (EntityBase)entityListTarget[i]; if (!entityTarget.IsDeleted) { EntityBase entitySource = (EntityBase)((ISearchable)entityListSource).GetEntityById(entityTarget.UniqueIdentifier); if (entitySource != null) { entityTarget.Merge(entitySource); } else { entityListTarget.Remove(entityTarget); } } } foreach (EntityBase entitySource in entityListSource) { EntityBase entityTarget = (EntityBase)((ISearchable)entityListTarget).GetEntityById(entitySource.UniqueIdentifier); if (entityTarget == null) { entityListTarget.Add(entitySource); } else if (entitySource.IsDeleted) { entityTarget.SetDeleted(true); } } } } // else if the property is an entity... else if (propertyInfo.PropertyType.IsSubclassOf(typeof(EntityBase))) { EntityBase entityBaseTarget = propertyInfo.GetValue(this, null) as EntityBase; EntityBase entityBaseSource = propertyInfo.GetValue(entity, null) as EntityBase; if ((entityBaseTarget != null) && (entityBaseSource != null)) { if (entityBaseTarget.UniqueIdentifier == entityBaseSource.UniqueIdentifier) { entityBaseTarget.Replace(entityBaseSource); } else if (propertyInfo.CanWrite) { propertyInfo.SetValue(this, propertyInfo.GetValue(entity, null), null); } } else if ((entityBaseSource != null) && (entityBaseTarget == null)) { if (propertyInfo.CanWrite) { propertyInfo.SetValue(this, ((ICloneable)propertyInfo.GetValue(entity, null)).Clone(), null); } } else { if (propertyInfo.CanWrite) { propertyInfo.SetValue(this, propertyInfo.GetValue(entity, null), null); } } } else // just copy the value or object { if (propertyInfo.CanWrite) { propertyInfo.SetValue(this, propertyInfo.GetValue(entity, null), null); } } } }