Exemplo n.º 1
0
        private IEnumerable <string> CreateTableUniqueConstraints(Type type, ClusterAttribute clusterAttribute)
        {
            List <string> results = new List <string>();

            if (PrimaryKeyColumns(type, markedOnly: true).Any())
            {
                results.Add($"CONSTRAINT [U_{GetConstraintBaseName(type)}_Id] UNIQUE {clusterAttribute.Syntax(ClusterOption.Identity)}([Id])");
            }

            results.AddRange(type.GetProperties().Where(pi => pi.HasAttribute <UniqueKeyAttribute>()).Select(pi =>
            {
                UniqueKeyAttribute attr = pi.GetCustomAttribute <UniqueKeyAttribute>();
                return($"CONSTRAINT [U_{GetConstraintBaseName(type)}_{pi.SqlColumnName()}] UNIQUE {attr.GetClusteredSyntax()}([{pi.SqlColumnName()}])");
            }));

            results.AddRange(type.GetCustomAttributes <UniqueKeyAttribute>().Select((u, i) =>
            {
                string constrainName = (string.IsNullOrEmpty(u.ConstraintName)) ? $"U_{GetConstraintBaseName(type)}_{i}" : u.ConstraintName;
                return($"CONSTRAINT [{constrainName}] UNIQUE {u.GetClusteredSyntax()}({string.Join(", ", u.ColumnNames.Select(col => $"[{col}]"))})");
            }));

            return(results);
        }
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);
            //        }
            //    }
            //}
        }