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); }
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); }