예제 #1
0
        /// <summary>
        /// Gets a property's value
        /// </summary>
        public static object GetValue(object obj, string propertyName)
        {
            if (obj is IDwarf)
            {
                var type = DwarfHelper.DeProxyfy(obj);

                if (!Cfg.PropertyExpressions[type].ContainsKey(propertyName))
                {
                    throw new ApplicationException(type.Name + " doesn't have a property: " + propertyName);
                }

                return(Cfg.PropertyExpressions[type][propertyName].GetValue(obj));
            }
            else
            {
                var type = obj.GetType();
                var pi   = type.GetProperty(propertyName);

                if (pi == null)
                {
                    throw new ApplicationException(type.Name + " doesn't have a property: " + propertyName);
                }

                return(pi.GetValue(obj, null));
            }
        }
예제 #2
0
        /// <summary>
        /// Restores the object's properties to their original values
        /// </summary>
        public void Reset()
        {
            if (originalValues == null)
            {
                throw new InvalidOperationException("You cannot reset a new object. Just create a new one?");
            }

            foreach (var kvp in originalValues)
            {
                PropertyHelper.SetValue(this, kvp.Key, kvp.Value);
            }

            ResetFKProperties();

            foreach (var ep in DwarfHelper.GetOneToManyProperties(this))
            {
                var key = GetCollectionKey(ep.Name);
                CacheManager.RemoveKey(key);
            }

            foreach (var ep in DwarfHelper.GetManyToManyProperties(this))
            {
                var key = GetCollectionKey(ep.Name);
                CacheManager.RemoveKey(key);
            }

            if (oneToManyAlternateKeys != null)
            {
                oneToManyAlternateKeys.Clear();
            }
        }
예제 #3
0
        /// <summary>
        /// Sets a property's value
        /// </summary>
        public static void SetValue(object obj, string propertyName, object value)
        {
            if (obj is IDwarf)
            {
                var type = DwarfHelper.DeProxyfy(obj);

                if (!Cfg.PropertyExpressions[type].ContainsKey(propertyName))
                {
                    throw new ApplicationException(type.Name + " doesn't have a property: " + propertyName);
                }

                var ep = Cfg.PropertyExpressions[type][propertyName];

                if (ep.CanWrite)
                {
                    ep.SetValue(obj, value);
                }
            }
            else
            {
                var type = obj.GetType();
                var pi   = type.GetProperty(propertyName);

                if (pi == null)
                {
                    throw new ApplicationException(type.Name + " doesn't have a property: " + propertyName);
                }

                if (pi.CanWrite)
                {
                    pi.SetValue(obj, value, null);
                }
            }
        }
예제 #4
0
        public static ExpressionProperty GetProperty(Type type, string propertyName)
        {
            DwarfHelper.DeProxyfy(ref type);

            return(Cfg.PropertyExpressions[type].ContainsKey(propertyName)
                       ? Cfg.PropertyExpressions[type][propertyName]
                       : null);
        }
예제 #5
0
        internal static string GetUserKey <T>(T obj, Guid?alternateId = null) where T : Dwarf <T>, new()
        {
            var objectKey = typeof(T).Implements <ICompositeId>()
                                   ? DwarfHelper.GetUniqueKeyForCompositeId(obj)
                                   : alternateId.HasValue ? alternateId.Value.ToString() : obj.Id.ToString();

            return(GetUserKey(objectKey));
        }
예제 #6
0
 /// <summary>
 /// Default Constructor
 /// </summary>
 public DwarfList()
 {
     if (typeof(T).Implements <IDwarf>())
     {
         sortProperty = DwarfHelper.GetOrderByProperty <T>();
         sortAsc      = DwarfHelper.GetOrderByDirection <T>().IsNullOrEmpty();
     }
 }
예제 #7
0
        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());
        }
예제 #8
0
        /// <summary>
        /// Returns true if the object contains faulty Foreign Key values
        /// </summary>
        private static IEnumerable <string> FaultyForeignKeys(IDwarf obj)
        {
            foreach (var pi in Cfg.FKProperties[DwarfHelper.DeProxyfy(obj)])
            {
                var att = DwarfPropertyAttribute.GetAttribute(pi.ContainedProperty);

                if (!att.IsNullable && (pi.GetValue(obj) == null || !((IDwarf)pi.GetValue(obj)).IsSaved))
                {
                    yield return(pi.Name);
                }
            }
        }
예제 #9
0
        /// <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();
        }
예제 #10
0
        /// <summary>
        /// Creates and returns an AuditLogEventTrace object for every modified OneToMany relationship
        /// </summary>
        private IEnumerable <AuditLogEventTrace> CreateTraceEventsForOneToMany()
        {
            if (!IsSaved)
            {
                return(new AuditLogEventTrace[0]);
            }

            return(from ep in DwarfHelper.GetOneToManyProperties(this)
                   where IsCollectionInitialized(ep.ContainedProperty)
                   let list = ep.GetValue(this)
                              let adds = ((IList)ep.PropertyType.GetMethod("GetAddedItems").Invoke(list, null)).Cast <IDwarf>().ToList()
                                         let dels = ((IList)ep.PropertyType.GetMethod("GetDeletedItems").Invoke(list, null)).Cast <IDwarf>().ToList()
                                                    where adds.Count > 0 || dels.Count > 0
                                                    select new AuditLogEventTrace {
                PropertyName = ep.Name, NewValue = list
            });
        }
예제 #11
0
        /// <summary>
        /// Stores an AuditLog object for the ongoing transaction
        /// </summary>
        public static IAuditLog Logg <T>(IDwarf obj, AuditLogTypes auditLogType, params AuditLogEventTrace[] auditUpdateEvents)
        {
            var type = DwarfHelper.DeProxyfy(obj);

            if (type.Implements <IAuditLogless>() || type.Implements <IAuditLog>())
            {
                return(null);
            }

            var al = new AuditLog
            {
                ClassType    = type.Name,
                AuditLogType = auditLogType,
                UserName     = DwarfContext <T> .GetConfiguration().UserService.CurrentUser != null ? DwarfContext <T> .GetConfiguration().UserService.CurrentUser.UserName : string.Empty,
                TimeStamp    = DateTime.Now,
                ObjectValue  = obj.ToString(),
            };

            if (!type.Implements <ICompositeId>())
            {
                al.ObjectId = obj.Id.ToString();
            }
            else
            {
                foreach (var ep in DwarfHelper.GetPKProperties(type))
                {
                    al.ObjectId += string.Format("[{0}: {1}]", ep.Name, ep.GetValue(obj));
                }
            }

            if (auditLogType != AuditLogTypes.Created)
            {
                al.AuditDetails = "<?xml version=\"1.0\"?><Properties>";

                foreach (var auditUpdateEvent in auditUpdateEvents)
                {
                    al.AuditDetails += auditUpdateEvent.ToXml().ToString();
                }

                al.AuditDetails += "</Properties>";
            }

            DwarfContext <T> .GetDatabase().Insert <T, AuditLog>(al);

            return(al);
        }
예제 #12
0
        /// <summary>
        /// Helper method for the proxy classes's MSIL generated foreign key methods
        /// </summary>
        protected TY GetProperty <TY>(string propertyName, ref TY backingField, ref bool isAccessed) where TY : Dwarf <TY>, new()
        {
            if (isAccessed)
            {
                return(backingField);
            }

            var orgValue = GetOriginalValue(propertyName);

            if (orgValue != null)
            {
                backingField = (TY)Cfg.LoadExpressions[DwarfHelper.DeProxyfy(typeof(TY))]((Guid)orgValue);
            }

            isAccessed = true;

            return(backingField);
        }
예제 #13
0
        /// <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());
        }
예제 #14
0
        /// <summary>
        /// Automatically handles default persistance operations over DwarfLists for OneToManyRelationships.
        /// Should a manual persistance be used via PersistOneToMany, do so before the base call in AppendStore
        /// </summary>
        private void PersistOneToManyCollections()
        {
            foreach (var pi in DwarfHelper.GetOneToManyProperties(this))
            {
                if (!IsCollectionInitialized(pi.ContainedProperty))
                {
                    continue;
                }

                var propertyName = pi.Name;
                var propertyAtt  = OneToManyAttribute.GetAttribute(pi.ContainedProperty);

                if (propertyAtt == null)
                {
                    throw new NullReferenceException(propertyName + " is missing the OneToMany attribute...");
                }

                var obj = (IDwarfList)PropertyHelper.GetValue(this, propertyName);

                var list = obj.Cast <IDwarf>().ToList();

                var owningProp = oneToManyAlternateKeys.ContainsKey(propertyName) ? oneToManyAlternateKeys[propertyName] : GetType().Name;
                list.ForEach(x => PropertyHelper.SetValue(x, owningProp, this));
                var deleteObjects = obj.GetDeletedItems();

                if (propertyAtt.IsInverse)
                {
                    deleteObjects.ForEach(x => PropertyHelper.SetValue(x, owningProp, null));
                    deleteObjects.SaveAllInternal <T>();
                }
                else
                {
                    deleteObjects.DeleteAllInternal <T>();
                }

                list.SaveAllInternal <T>();

                oneToManyAlternateKeys.Remove(propertyName);
            }
        }
예제 #15
0
        /// <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);
        }
예제 #16
0
        /// <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));
                }
            }
        }
예제 #17
0
        /// <summary>
        /// Automatically handles default persistance operations over DwarfLists for ManyToManyRelationships.
        /// Should a manual persistance be used via PersistManyToMany, do so before the base call in AppendStore
        /// </summary>
        private void PersistManyToManyCollections()
        {
            foreach (var pi in DwarfHelper.GetManyToManyProperties(this))
            {
                if (!IsCollectionInitialized(pi.ContainedProperty))
                {
                    continue;
                }

                var tableName = ManyToManyAttribute.GetTableName(GetType(), pi.ContainedProperty);

                var obj = (IDwarfList)pi.GetValue(this);

                foreach (var deletedItem in obj.GetDeletedItems())
                {
                    DeleteManyToMany(this, deletedItem, tableName);
                }

                foreach (var addedItem in obj.GetAddedItems())
                {
                    PersistManyToMany(this, addedItem, tableName);
                }
            }
        }
예제 #18
0
 /// <summary>
 /// Returns the database object for the supplied typeq
 /// </summary>
 internal static IDatabase GetDatabase(Type type)
 {
     return(Cfg.Databases[DwarfHelper.DeProxyfy(type).Assembly]);
 }
예제 #19
0
        internal static IEnumerable <ExpressionProperty> GetProperties(Type type)
        {
            DwarfHelper.DeProxyfy(ref type);

            return(Cfg.PropertyExpressions[type].Values);
        }
예제 #20
0
 /// <summary>
 /// Returns true if the supplied object contains a property by the specified name
 /// </summary>
 public static bool HasProperty(Type type, string propertyName)
 {
     return(Cfg.PropertyExpressions[DwarfHelper.DeProxyfy(type)].ContainsKey(propertyName));
 }