private void OnBeforeDeleteInternal() { //We want to persist all the Inverse OneToManyCollection upon deletion. Let's remove all lists that doesn't //need persistance first (all objects therein will be deleted in the database via delete cascades anyways) foreach (var pi in DwarfHelper.GetOneToManyProperties(this)) { var propertyAtt = OneToManyAttribute.GetAttribute(pi.ContainedProperty); if (propertyAtt == null) { throw new NullReferenceException(pi.Name + " is missing the OneToMany attribute..."); } if (!propertyAtt.IsInverse) { continue; } var obj = (IDwarfList)pi.GetValue(this); var owningProp = oneToManyAlternateKeys.ContainsKey(pi.Name) ? oneToManyAlternateKeys[pi.Name] : GetType().Name; obj.Cast <IDwarf>().ForEachX(x => PropertyHelper.SetValue(x, owningProp, null)); obj.SaveAllInternal <T>(); } if (DbContextHelper <T> .DbContext.IsAuditLoggingSuspended || DwarfContext <T> .GetConfiguration().AuditLogService == null) { return; } var traces = (from ep in DwarfHelper.GetDBProperties(GetType()).Where(x => !x.Name.Equals("Id")) let oldValue = originalValues[ep.Name] where oldValue != null && (oldValue is string? !string.IsNullOrEmpty(oldValue.ToString()) : true) select new AuditLogEventTrace { PropertyName = ep.Name, OriginalValue = oldValue }).ToArray(); var collectionTraces = (from ep in DwarfHelper.GetGemListProperties(GetType()) let oldValue = (IGemList)ep.GetValue(this) where oldValue != null && oldValue.Count > 0 select new AuditLogEventTrace { PropertyName = ep.Name, OriginalValue = oldValue }).ToArray(); var many2ManyTraces = (from ep in DwarfHelper.GetManyToManyProperties(GetType()) let oldValue = ep.GetValue(this) where oldValue != null && ((IList)oldValue).Count > 0 select new AuditLogEventTrace { PropertyName = ep.Name, OriginalValue = oldValue }).ToArray(); DwarfContext <T> .GetConfiguration().AuditLogService.Logg(this, AuditLogTypes.Deleted, traces.Union(collectionTraces).Union(many2ManyTraces).ToArray()); }
/// <summary> /// Restores the object's properties to their original values /// </summary> public void Refresh() { //Fetch the original values from the database (bypass the cache...) var originalObject = DwarfContext <T> .GetDatabase().SelectReferencing <T>(new QueryBuilder().Select <T>().From <T>().Where(this, Cfg.PKProperties[DwarfHelper.DeProxyfy(this)]), false, true).FirstOrDefault(); if (originalObject != null) { foreach (var ep in DwarfHelper.GetDBProperties(GetType())) { SetOriginalValue(ep.Name, ep.GetValue(originalObject)); } } //Else should we throw an exception since the object has been deleted from the DB? Reset(); }
/// <summary> /// Creates and returns an AuditLogEventTrace object for every modified property /// </summary> private AuditLogEventTrace[] CreateTraceEventsForProperties() { if (!IsSaved) { return(new AuditLogEventTrace[0]); } if (originalValues == null) { var fromDB = !typeof(T).Implements <ICompositeId>() ? Load(Id.Value) : Load(DwarfHelper.GetPKProperties <T>().Select(x => new WhereCondition <T> { ColumnPi = x.ContainedProperty, Value = x.GetValue(this) }).ToArray()); if (fromDB == null) { return(new AuditLogEventTrace[0]); } originalValues = fromDB.originalValues; } var dbProps = from ep in DwarfHelper.GetDBProperties(GetType()) let oldValue = originalValues[ep.Name] let x = ep.GetValue(this) let newValue = x is IDwarf ? ((IDwarf)ep.GetValue(this)).Id : ep.GetValue(this) where (oldValue != null && !oldValue.Equals(newValue)) || (oldValue == null && newValue != null) select new AuditLogEventTrace { PropertyName = ep.Name, OriginalValue = oldValue, NewValue = newValue }; var collections = from ep in DwarfHelper.GetGemListProperties(GetType()) where IsCollectionInitialized(ep.ContainedProperty) let x = (IGemList)ep.GetValue(this) let newValue = x let oldValue = x.Parse((string)originalValues[ep.Name] ?? string.Empty) where (oldValue != null && !oldValue.ComparisonString.Equals(newValue.ComparisonString)) || (oldValue == null && newValue != null) select new AuditLogEventTrace { PropertyName = ep.Name, OriginalValue = oldValue, NewValue = newValue }; return(dbProps.Concat(collections).ToArray()); }
/// <summary> /// Dwarf comparison is done via the Id property /// </summary> public override bool Equals(object obj) { if (obj is IDwarf) { var type = DwarfHelper.DeProxyfy(GetType()); if (type != DwarfHelper.DeProxyfy(obj)) { return(false); } if (!type.Implements <ICompositeId>()) { //Should both objects not be stored they'll both have null as Id, thus we check all the properties to find out if they might be the same object //We also dubbelcheck all unique properties (if existant) to make sure they're NOT equal if (!Id.HasValue && !((IDwarf)obj).Id.HasValue) { var propertiesMatch = DwarfHelper.GetDBProperties(type).Where(ep => ep.GetValue(this) != null && ep.GetValue(obj) != null).All(pi => pi.GetValue(this).Equals(pi.GetValue(obj))); var uniqueProps = DwarfHelper.GetUniqueDBProperties <T>(type).ToList(); if (uniqueProps.Any()) { var uniquePropertiesMatch = uniqueProps.All(ep => ep.GetValue(this) == null ? ep.GetValue(obj) == null : ep.GetValue(this).Equals(ep.GetValue(obj))); return(uniquePropertiesMatch && propertiesMatch); } return(propertiesMatch); } return(Id == ((IDwarf)obj).Id); } return(Cfg.PKProperties[type].All(ep => ep.GetValue(this) == null ? ep.GetValue(obj) == null : ep.GetValue(this).Equals(ep.GetValue(obj)))); } return(false); }
/// <summary> /// Append the Save method with additional modifications /// </summary> private void OnAfterSaveInternal() { foreach (var ep in DwarfHelper.GetDBProperties(GetType())) { SetOriginalValue(ep.Name, ep.GetValue(this)); } foreach (var ep in DwarfHelper.GetGemListProperties(GetType())) { if (IsCollectionInitialized(ep.ContainedProperty)) { SetOriginalValue(ep.Name, ep.GetValue(this)); } } foreach (var ep in DwarfHelper.GetManyToManyProperties(GetType())) { if (IsCollectionInitialized(ep.ContainedProperty)) { SetOriginalValue(ep.Name, ep.GetValue(this)); } } }