Exemplo n.º 1
0
        public static ITable ToSchemaTable(this Type type, IDataProvider provider)
        {
            string tableName = type.Name;

            /*
             * 修 改 人:Empty(AllEmpty)
             * QQ    群:327360708
             * 博客地址:http://www.cnblogs.com/EmptyFS/
             * 修改时间:2013-07-27
             * 修改说明:去除生成的数据表对应名称自动加复数(s)功能以及由此产生的异常
             *********************************************/

            //复数处理,即如果当前表名为指定的字符串相匹配,则在名称的后面加s,做复数处理
            //tableName = tableName.MakePlural();
            /*********************************************/

            var result = new DatabaseTable(tableName, provider);

            result.ClassName = type.Name;

            var typeAttributes = type.GetCustomAttributes(typeof(IClassMappingAttribute), false);

            foreach (IClassMappingAttribute attr in typeAttributes)
            {
                if (attr.Accept(result))
                {
                    attr.Apply(result);
                }
            }

            var props = type.GetProperties();

            foreach (var prop in props)
            {
                var attributes = prop.GetCustomAttributes(false);
                if (ColumnIsIgnored(attributes))
                {
                    continue;
                }

                if (CanGenerateSchemaFor(prop.PropertyType))
                {
                    var column = new DatabaseColumn(prop.Name, result);
                    column.PropertyName = prop.Name;
                    bool isNullable = prop.PropertyType.Name.Contains("Nullable");

                    column.DataType = IdentifyColumnDataType(prop.PropertyType, isNullable);

                    if (column.DataType == DbType.Decimal || column.DataType == DbType.Double)
                    {
                        //default to most common;
                        column.NumberScale      = 2;
                        column.NumericPrecision = 10;
                    }
                    else if (column.DataType == DbType.String)
                    {
                        column.MaxLength = 255;
                    }
                    else if (column.DataType == DbType.Binary)
                    {
                        isNullable = true;
                    }

                    if (isNullable)
                    {
                        column.IsNullable = true;
                    }

                    // Now work with attributes
                    foreach (IPropertyMappingAttribute attr in attributes.Where(x => x is IPropertyMappingAttribute))
                    {
                        /*
                         *
                         * 修改时间:2014-05-12
                         * 修改说明:标识主键列
                         *********************************************/
                        //当主键的自定义属性设置了[SubSonicPrimaryKeyAttribute]时,则认为该列为表中的主键
                        if (attr.GetType().Name == "SubSonicPrimaryKeyAttribute")
                        {
                            column.IsPrimaryKey = true;
                        }

                        if (attr.Accept(column))
                        {
                            attr.Apply(column);
                        }
                    }

                    result.Columns.Add(column);
                }
                else if (IsRelationColumm(attributes))
                {
                    if (!IsPropertyDeclaredVirtual(prop))
                    {
                        throw new InvalidOperationException(String.Format(
                                                                "Property {0} of type {1} marked as relation must be declared virtual to allow dynamic proxy mechanisms work correctly!",
                                                                prop.Name, prop.DeclaringType.Name));
                    }

                    var innerProp = prop;

                    result.AddRelation(() =>
                    {
                        var relation = new DatabaseRelation(innerProp.Name, result);

                        foreach (IRelationMappingAttribute attr in attributes.Where(x => x is IRelationMappingAttribute))
                        {
                            if (attr.Accept(relation, innerProp))
                            {
                                attr.Apply(relation, innerProp);
                            }
                        }

                        return(relation);
                    });
                }
            }

            //if the PK is still null-look for a column called [tableName]ID - if it's there then make it PK
            if (result.PrimaryKey == null)
            {
                var pk = (result.GetColumn(type.Name + "_ID") ?? result.GetColumn(type.Name + "ID") ?? result.GetColumn("ID")) ?? result.GetColumn("Key");

                if (pk != null)
                {
                    pk.IsPrimaryKey = true;
                    //if it's an INT then AutoIncrement it
                    if (pk.IsNumeric)
                    {
                        pk.AutoIncrement = true;
                    }
                    else if (pk.IsString && pk.MaxLength == 0)
                    {
                        pk.MaxLength = 255;
                    }
                    //} else {
                    //    pk = new DatabaseColumn(type.Name + "ID", result);
                    //    pk.DataType = DbType.Int32;
                    //    pk.IsPrimaryKey = true;
                    //    pk.AutoIncrement = true;
                    //    result.Columns.Insert(0, pk);
                }
            }

            //we should have a PK at this point
            //if not, throw :)
            if (result.PrimaryKey == null)
            {
                throw new InvalidOperationException("Can't decide which property to consider the Key - you can create one called 'ID' or mark one with SubSonicPrimaryKey attribute");
            }
            return(result);
        }
Exemplo n.º 2
0
        public static ITable ToSchemaTable(this Type type, IDataProvider provider)
        {
            string tableName = type.Name;

            tableName = tableName.MakePlural();
            var result = new DatabaseTable(tableName, provider);

            result.ClassName = type.Name;

            var typeAttributes = type.GetCustomAttributes(typeof(IClassMappingAttribute), false);

            foreach (IClassMappingAttribute attr in typeAttributes)
            {
                if (attr.Accept(result))
                {
                    attr.Apply(result);
                }
            }

            var props = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);

            foreach (var prop in props)
            {
                if (prop.GetSetMethod() == null)
                {
                    continue;
                }

                var attributes = prop.GetCustomAttributes(false);
                if (ColumnIsIgnored(attributes))
                {
                    continue;
                }

                if (CanGenerateSchemaFor(prop.PropertyType))
                {
                    var column = new DatabaseColumn(prop.Name, result);
                    column.PropertyName = prop.Name;
                    bool isNullable = prop.PropertyType.Name.Contains("Nullable");

                    column.DataType = IdentifyColumnDataType(prop.PropertyType, isNullable);

                    if (column.DataType == DbType.Decimal || column.DataType == DbType.Double)
                    {
                        //default to most common;
                        column.NumberScale      = 2;
                        column.NumericPrecision = 10;
                    }

                    /*else if(column.DataType == DbType.String)
                     * {
                     *  column.MaxLength = 255;
                     * }*/
                    else if (column.DataType == DbType.Binary)
                    {
                        isNullable = true;
                    }

                    if (isNullable)
                    {
                        column.IsNullable = true;
                    }

                    // Now work with attributes
                    foreach (IPropertyMappingAttribute attr in attributes.Where(x => x is IPropertyMappingAttribute))
                    {
                        if (attr.Accept(column))
                        {
                            attr.Apply(column);
                        }
                    }

                    result.Columns.Add(column);
                }
                else if (IsRelationColumm(attributes))
                {
                    if (!IsPropertyDeclaredVirtual(prop))
                    {
                        throw new InvalidOperationException(String.Format(
                                                                "Property {0} of type {1} marked as relation must be declared virtual to allow dynamic proxy mechanisms work correctly!",
                                                                prop.Name, prop.DeclaringType.Name));
                    }

                    var innerProp = prop;

                    result.AddRelation(() =>
                    {
                        var relation = new DatabaseRelation(innerProp.Name, result);

                        foreach (IRelationMappingAttribute attr in attributes.Where(x => x is IRelationMappingAttribute))
                        {
                            if (attr.Accept(relation, innerProp))
                            {
                                attr.Apply(relation, innerProp);
                            }
                        }

                        return(relation);
                    });
                }
            }

            //if the PK is still null-look for a column called [tableName]ID - if it's there then make it PK
            if (result.PrimaryKey == null)
            {
                var pk = (result.GetColumn(type.Name + "ID") ?? result.GetColumn("ID")) ?? result.GetColumn("Key");

                if (pk != null)
                {
                    pk.IsPrimaryKey = true;
                    //if it's an INT then AutoIncrement it
                    if (pk.IsNumeric)
                    {
                        pk.AutoIncrement = true;
                    }
                    else if (pk.IsString && pk.MaxLength == 0)
                    {
                        pk.MaxLength = 255;
                    }
                    //} else {
                    //    pk = new DatabaseColumn(type.ColumnName + "ID", result);
                    //    pk.DataType = DbType.Int32;
                    //    pk.IsPrimaryKey = true;
                    //    pk.AutoIncrement = true;
                    //    result.Columns.Insert(0, pk);
                }
            }

            //we should have a PK at this point
            //if not, throw :)
            if (result.PrimaryKey == null)
            {
                throw new InvalidOperationException("Can't decide which property to consider the Key - you can create one called 'ID' or mark one with SubSonicPrimaryKey attribute");
            }
            return(result);
        }