Exemplo n.º 1
0
        private dynamic NextNumber(Type type, PropertyInfoItem prop)
        {
            dynamic defValue = ValueHelper.DefaultOf(prop.PropertyType);

            if (!prop.IsAutonumber)
            {
                return(defValue);
            }

            dynamic value = defValue;

            lock (GetLock())
            {
                if (this.Contains(type, prop.PropertyName))
                {
                    value = this.GetNext(type, prop.PropertyName, prop.IdentityIncrement);
                    if (value < prop.IdentitySeed)
                    {
                        value = prop.IdentitySeed;
                        this.Update(type, prop.PropertyName, value);
                    }
                }
                else if (this.findLastDelegate != null)
                {
                    MethodInfo numOpsSumGenericMethod = typeof(NumericOperations)
                                                        .GetMethod("Sum")
                                                        .MakeGenericMethod(new Type[] { prop.PropertyType });

                    var last = this.findLastDelegate(type);
                    if (last == null)
                    {
                        value = prop.IdentitySeed;
                    }
                    else
                    {
                        value = numOpsSumGenericMethod.Invoke(
                            null,
                            new object[] {
                            new object[]
                            {
                                prop.Property.GetValue(last),
                                prop.IdentityIncrement
                            }
                        });
                    }
                    this.Set(type, prop.PropertyName, numOpsSumGenericMethod, value);
                }
            }
            return(value);
        }
Exemplo n.º 2
0
        internal void LoadType(Type type)
        {
            if (type == null || type == typeof(object))
            {
                return;
            }

            List <PropertyInfoItem> typeProps  = null;
            List <PropertyInfo>     props      = null;
            List <Type>             innerTypes = null;

            //double-check lock pattern; optemized thread-safe
            if (!properties.ContainsKey(type.FullName) && GetPropertyTypeCategory(type) == PropertyTypeCategory.Class)
            {
                lock (locker)
                {
                    innerTypes = new List <Type>();

                    if (!properties.ContainsKey(type.FullName) && GetPropertyTypeCategory(type) == PropertyTypeCategory.Class)
                    {
                        typeProps = new List <PropertyInfoItem>();

                        // props = System.ComponentModel.TypeDescriptor.GetProperties(type.GetProperties);
                        props = type.GetProperties().Where(s => s.GetAccessors(false).Any()).ToList();
                        foreach (var prop in props)
                        {
                            var atts = prop.GetCustomAttributes(false).ToArray();
                            if (atts.OfType <NotMappedAttribute>().Any())
                            {
                                continue;
                            }

                            PropertyTypeCategory propTypeCategory = GetPropertyTypeCategory(prop.PropertyType);
                            PropertyInfoItem     propInfoItem     = new PropertyInfoItem()
                            {
                                Type          = type,
                                TypeCategory  = propTypeCategory,
                                Property      = prop,
                                PropertyName  = prop.Name,
                                PropertyType  = prop.PropertyType,
                                IsGenericType = prop.PropertyType == typeof(object),
                                IsReadOnly    = !prop.CanWrite
                            };

                            var primaryKeyAtt = atts.OfType <PrimaryKeyAttribute>().FirstOrDefault();
                            propInfoItem.IsPrimaryKey = null != primaryKeyAtt;

                            var foreignKeyAtts = atts.OfType <ForeignKeyAttribute>();
                            if (foreignKeyAtts.Any())
                            {
                                propInfoItem.ForeignKeys = foreignKeyAtts.Cast <ForeignKeyAttribute>().ToList();
                            }

                            var parentKeyAtts = atts.OfType <ParentKeyAttribute>();
                            if (parentKeyAtts.Any())
                            {
                                propInfoItem.ParentKeys = parentKeyAtts.Cast <ParentKeyAttribute>().ToList();
                            }

                            PropertyAttribute propertyAtt = atts.OfType <PropertyAttribute>().FirstOrDefault();
                            if (null != propertyAtt)
                            {
                                propInfoItem.Cascade      = propertyAtt.Cascade;
                                propInfoItem.IsAutonumber = propertyAtt.AutoNumber;
                                //propInfoItem.ForceAutoNumber = propertyAtt.OverrideAutoNumber;
                                propInfoItem.IsIndexed         = propertyAtt.Indexed;
                                propInfoItem.ValuePosition     = propertyAtt.Position;
                                propInfoItem.IdentityIncrement = propertyAtt.IdentityIncrement;
                                propInfoItem.IdentitySeed      = propertyAtt.IdentitySeed;
                            }

                            RequiredAttribute requiredAtt = atts.OfType <RequiredAttribute>().FirstOrDefault();
                            propInfoItem.IsRequired = null != requiredAtt;

                            UniqueKeyAttribute uniqueKeyAtt = atts.OfType <UniqueKeyAttribute>().FirstOrDefault();
                            propInfoItem.IsUnique = null != uniqueKeyAtt;

                            MarkupAttribute markupAtt = atts.OfType <MarkupAttribute>().FirstOrDefault();
                            propInfoItem.IsMarkup = null != markupAtt;

                            CryptoAttribute cryptoAtt = atts.OfType <CryptoAttribute>().FirstOrDefault();
                            propInfoItem.Encryption = (null != cryptoAtt) ? cryptoAtt.Method : CryptoMethod.None;

                            ChildrenAttribute childrenAtt = atts.OfType <ChildrenAttribute>().FirstOrDefault();
                            //InheritedAttribute inheritedAtt = (InheritedAttribute)atts
                            //    .FirstOrDefault(s => s.GetType() == typeof(InheritedAttribute));
                            if (null != childrenAtt)
                            {
                                propInfoItem.ReferenceType       = PropertyReferenceType.Children;
                                propInfoItem.Cascade             = CascadeOptions.Delete;
                                propInfoItem.ChildParentProperty = childrenAtt.RemoteParentProperty;
                            }

                            GenericTypePropertyAttribute genericTypeAtt = atts.OfType <GenericTypePropertyAttribute>().FirstOrDefault();
                            if (prop.PropertyType == typeof(object) && null != genericTypeAtt)
                            {
                                propInfoItem.GenericTypeProperty = genericTypeAtt.Name;
                            }

                            //setting reference type
                            if (propInfoItem.ReferenceType != PropertyReferenceType.Children)
                            {
                                if (propTypeCategory == PropertyTypeCategory.None)
                                {
                                    propInfoItem.ReferenceType = PropertyReferenceType.None;
                                }
                                else if (foreignKeyAtts.Any())
                                {
                                    if (prop.PropertyType.GetProperties()
                                        .Where(s =>
                                               s.PropertyType == type &&
                                               null != s.GetCustomAttribute <ForeignKeyAttribute>(false)).Any())
                                    {
                                        propInfoItem.ReferenceType = PropertyReferenceType.SelfForeign;
                                    }
                                    else
                                    {
                                        propInfoItem.ReferenceType = PropertyReferenceType.Foreign;
                                    }
                                }
                                else if (parentKeyAtts.Any())
                                {
                                    propInfoItem.ReferenceType = PropertyReferenceType.Parent;
                                }
                                else
                                {
                                    propInfoItem.ReferenceType = PropertyReferenceType.Reference;

                                    // PropertyDescriptorCollection propTypeProps = TypeDescriptor.GetProperties(prop.PropertyType);
                                    var propTypeProps = type.GetProperties().Where(s => s.GetAccessors(false).Any()).ToList();

                                    System.Collections.IEnumerator propTypePropsItems = propTypeProps.GetEnumerator();
                                    foreach (var propTypeProp in propTypeProps)
                                    {
                                        var propTypePropAtts = propTypeProp.GetCustomAttributes(false).ToArray();
                                        if (propTypePropAtts.OfType <PrimaryKeyAttribute>().Any())
                                        {
                                            propInfoItem.ReferenceType = PropertyReferenceType.Complex;
                                            propInfoItem.Cascade       = CascadeOptions.Delete;
                                            break;
                                        }
                                    }
                                }
                            }

                            if (propTypeCategory == PropertyTypeCategory.Array)
                            {
                                propInfoItem.CollectionItemType = prop.PropertyType.GetElementType();
                            }
                            else if (propTypeCategory == PropertyTypeCategory.GenericCollection)
                            {
                                propInfoItem.CollectionItemType = prop.PropertyType.GetGenericArguments().FirstOrDefault();
                            }

                            typeProps.Add(propInfoItem);

                            if (prop.PropertyType != type && (
                                    propTypeCategory == PropertyTypeCategory.Class ||
                                    propTypeCategory == PropertyTypeCategory.Array ||
                                    propTypeCategory == PropertyTypeCategory.GenericCollection))
                            {
                                if (prop.PropertyType.IsArray && prop.PropertyType.GetArrayRank() == 1)
                                {
                                    innerTypes.Add(prop.PropertyType.GetElementType());
                                }
                                else if (null != prop.PropertyType.GetTypeInfo().GetInterface("ICollection"))
                                {
                                    innerTypes.Add(prop.PropertyType.GetGenericArguments().FirstOrDefault());
                                }
                                else if (prop.PropertyType.GetTypeInfo().IsClass)
                                {
                                    innerTypes.Add(prop.PropertyType);
                                }
                            }
                        }

                        properties.Add(type.FullName, typeProps);

                        //if there is no PrimaryKey find a property with name Id and make it PrimaryKey
                        if (!typeProps.Any(s => s.IsPrimaryKey))
                        {
                            var primaryKeyProperty = typeProps.FirstOrDefault(s => s.PropertyName == "Id");
                            if (primaryKeyProperty != null)
                            {
                                primaryKeyProperty.IsPrimaryKey = true;
                                if (primaryKeyProperty.PropertyType != typeof(string))
                                {
                                    primaryKeyProperty.IsAutonumber = true;
                                }
                            }
                        }
                    }
                }

                //after loading all PropertyInfoItems validate them
                CheckReservedKeywords(type);

                //load types of inner reference type properties
                foreach (var innerType in innerTypes)
                {
                    LoadType(innerType);
                }
            }

            //else if (properties.ContainsKey(type.FullName))
            //{
            //    typeProps = Properties(type.FullName).ToList();
            //    props = System.ComponentModel.TypeDescriptor.GetProperties(type);
            //    foreach (PropertyDescriptor prop in props)
            //    {
            //        var propItems = typeProps.Select(s => s.Property).ToArray();
            //        if (propItems.Contains(prop))
            //            continue;

            //        var refType = GetPropertyTypeCategory(prop.PropertyType);
            //        if (refType == PropertyTypeCategory.Class ||
            //            refType == PropertyTypeCategory.Array ||
            //            refType == PropertyTypeCategory.GenericCollection)
            //        {
            //            if (prop.PropertyType.IsArray && prop.PropertyType.GetArrayRank() == 1)
            //                LoadType(prop.PropertyType.GetElementType());
            //            else if (null != prop.PropertyType.GetInterface("ICollection"))
            //                LoadType(prop.PropertyType.GetGenericArguments().FirstOrDefault());
            //            else if (prop.PropertyType.IsClass)
            //                LoadType(prop.PropertyType);
            //        }
            //    }
            //}
        }