/// <summary> /// 设置实体 /// </summary> /// <param name="includeComments"></param> /// <param name="includeExtendedPropertyComments"></param> private void SetupEntity(bool includeComments, ExtendedPropertyCommentsStyle includeExtendedPropertyComments) { string comments; if (includeComments) { comments = " // " + Name; if (IsPrimaryKey) { if (IsPrimaryKeyViaUniqueIndex) { comments += " (Primary key via unique index " + UniqueIndexName + ")"; } else { comments += " (Primary key)"; } } } else { comments = string.Empty; } if (includeExtendedPropertyComments == ExtendedPropertyCommentsStyle.AtEndOfField && !string.IsNullOrEmpty(ExtendedProperty)) { if (string.IsNullOrEmpty(comments)) { comments = " // " + ExtendedProperty; } else { comments += ". " + ExtendedProperty; } } if (IsPrimaryKey) { StringBuilder build = new StringBuilder(); build.AppendLine(string.Format("private {0} {1} _{2};", PropertyType, CodeFirstTools.CheckNullable(this), PropertyNameHumanCase.ToLower())); build.AppendLine(string.Format("public {0} {1} {2} {3} {4}", PropertyType, CodeFirstTools.CheckNullable(this), PropertyName, "{ get { return _" + PropertyNameHumanCase.ToLower() + " ; } set { this.Id = value; this._" + PropertyNameHumanCase.ToLower() + " = value; }}", comments)); Entity = build.ToString(); } else { Entity = string.Format("public {0}{1} {2} {3}{4}", PropertyType, CodeFirstTools.CheckNullable(this), PropertyName, IsStoreGenerated ? "{ get; internal set; }" : "{ get; set; }", comments); } }
/// <summary> /// 读取表空间信息 /// </summary> /// <param name="tableFilterExclude"></param> /// <param name="columnFilterExclude"></param> /// <param name="useCamelCase"></param> /// <param name="prependSchemaName"></param> /// <param name="includeComments"></param> /// <param name="includeExtendedPropertyComments"></param> /// <param name="tableRename"></param> /// <param name="schemaNameFilter"></param> /// <param name="updateColumn"></param> /// <returns></returns> public override Tables ReadSchema(Regex tableFilterExclude, Regex columnFilterExclude, bool useCamelCase, bool prependSchemaName, bool includeComments, ExtendedPropertyCommentsStyle includeExtendedPropertyComments, Func <string, string, string> tableRename, string schemaNameFilter, Func <Column, Table, Column> updateColumn) { var result = new Tables(); if (Cmd == null) { return(result); } Cmd.CommandText = TableSQL; if (Cmd.GetType().Name == "SqlCeCommand") { Cmd.CommandText = string.Empty; } else { Cmd.CommandTimeout = 600; } using (DbDataReader rdr = Cmd.ExecuteReader()) { var rxClean = new Regex("^(event|Equals|GetHashCode|GetType|ToString|repo|Save|IsNew|Insert|Update|Delete|Exists|SingleOrDefault|Single|First|FirstOrDefault|Fetch|Page|Query)$"); var lastTable = string.Empty; Table table = null; while (rdr.Read()) { string tableName = rdr["TABLENAME"].ToString().Trim(); if (tableFilterExclude != null && tableFilterExclude.IsMatch(tableName)) { continue; } string schema = rdr["SCHEMANAME"].ToString().Trim(); if (schemaNameFilter != null && !schema.Equals(schemaNameFilter, StringComparison.CurrentCultureIgnoreCase)) { continue; } if (lastTable != tableName || table == null) { // The data from the database is not sorted table = result.Find(x => x.Name == tableName && x.Schema == schema); if (table == null) { table = new Table { Name = tableName, Schema = schema, IsView = String.Compare(rdr["TABLETYPE"].ToString().Trim(), "View", StringComparison.OrdinalIgnoreCase) == 0, // Will be set later HasForeignKey = false, HasNullableColumns = false }; tableName = tableRename(tableName, schema); CodeFirstTools.SchemaName = schema; table.CleanName = CodeFirstTools.CleanUp(tableName); table.ClassName = Inflector.MakeSingular(table.CleanName); string singular = Inflector.MakeSingular(tableName); table.NameHumanCase = (useCamelCase ? Inflector.ToTitleCase(singular) : singular).Replace(" ", "").Replace("$", ""); //if ((string.Compare(table.Schema, "dbo", StringComparison.OrdinalIgnoreCase) != 0) && prependSchemaName) // table.NameHumanCase = table.Schema + "_" + table.NameHumanCase; // Check for table or C# name clashes if (CodeFirstTools.ReservedKeywords.Contains(table.NameHumanCase) || (useCamelCase && result.Find(x => x.NameHumanCase == table.NameHumanCase) != null)) { table.NameHumanCase += "1"; } result.Add(table); } } var col = CreateColumn(rdr, rxClean, table, useCamelCase, columnFilterExclude, updateColumn); if (col != null) { table.Columns.Add(col); } } } // Check for property name clashes in columns foreach (Column c in result.SelectMany(tbl => tbl.Columns.Where(c => tbl.Columns.FindAll(x => x.PropertyNameHumanCase == c.PropertyNameHumanCase).Count > 1))) { c.PropertyNameHumanCase = c.PropertyName; } if (includeExtendedPropertyComments != ExtendedPropertyCommentsStyle.None) { ReadExtendedProperties(result); } ReadUniqueIndexes(result); foreach (Table tbl in result) { tbl.Columns.ForEach(x => x.SetupEntityAndConfig(includeComments, includeExtendedPropertyComments)); } return(result); }
private static Column CreateColumn(IDataRecord rdr, Regex rxClean, Table table, bool useCamelCase, Regex columnFilterExclude, Func <Column, Table, Column> updateColumn) { try { if (rdr == null) { throw new ArgumentNullException("rdr"); } string typename = rdr["TYPENAME"].ToString().Trim().ToLower(); var scale = decimal.ToInt32(decimal.Parse(rdr["SCALE"].ToString())); var precision = decimal.ToInt32(decimal.Parse(rdr["PRECISION"].ToString())); if (typename.ToLower() == "number" && scale == 0 && precision == 0) { scale = int.MinValue; precision = 38; } var col = new Column { Name = rdr["COLUMNNAME"].ToString().Trim(), TypeName = typename, PropertyType = GetPropertyType(typename, ref scale, precision), MaxLength = decimal.ToInt32(decimal.Parse(rdr["MAXLENGTH"].ToString())), Precision = precision, Default = rdr["Default"].ToString().Trim(), DateTimePrecision = decimal.ToInt32(decimal.Parse(rdr["DATETIMEPRECISION"].ToString())), Scale = scale, Ordinal = decimal.ToInt32(decimal.Parse(rdr["ORDINAL"].ToString())), IsIdentity = rdr["ISIDENTITY"].ToString().Trim().ToLower() == "1", IsNullable = rdr["ISNULLABLE"].ToString().Trim().ToLower() == "1", IsStoreGenerated = rdr["ISSTOREGENERATED"].ToString().Trim().ToLower() == "1", IsPrimaryKey = rdr["PRIMARYKEY"].ToString().Trim().ToLower() == "1", PrimaryKeyOrdinal = decimal.ToInt32(decimal.Parse(rdr["PRIMARYKEYORDINAL"].ToString())), IsForeignKey = rdr["ISFOREIGNKEY"].ToString().Trim().ToLower() == "1" }; Assembly asm = Assembly.Load("EntityFramework"); Version v = new Version("5.0.0.0"); if (typename.ToLower() == "float" && asm.GetName().Version > v) { if (precision == 126) { col.Precision = 38; } else if (precision == 63) { col.Precision = 19; } } if (columnFilterExclude != null && !col.IsPrimaryKey && columnFilterExclude.IsMatch(col.Name)) { col.Hidden = true; } col.IsFixedLength = (typename.ToLower() == "char" || typename.ToLower() == "nchar"); col.IsUnicode = !(typename.ToLower() == "char" || typename.ToLower() == "varchar2" || typename.ToLower() == "clob" || typename.ToLower() == "long"); col.IsRowVersion = col.IsStoreGenerated && !col.IsNullable && typename == "timestamp"; if (col.IsRowVersion) { col.MaxLength = 8; } col.CleanUpDefault(); col.PropertyName = CodeFirstTools.CleanUp(col.Name); col.PropertyName = rxClean.Replace(col.PropertyName, "_$1"); // Make sure property name doesn't clash with class name if (col.PropertyName == table.NameHumanCase) { col.PropertyName = col.PropertyName + "_"; } col.PropertyNameHumanCase = (useCamelCase ? Inflector.ToTitleCase(col.PropertyName) : col.PropertyName).Replace(" ", ""); if (col.PropertyNameHumanCase == string.Empty) { col.PropertyNameHumanCase = col.PropertyName; } // Make sure property name doesn't clash with class name if (col.PropertyNameHumanCase == table.NameHumanCase) { col.PropertyNameHumanCase = col.PropertyNameHumanCase + "_"; } if (char.IsDigit(col.PropertyNameHumanCase[0])) { col.PropertyNameHumanCase = "_" + col.PropertyNameHumanCase; } if (CodeFirstTools.CheckNullable(col) != string.Empty) { table.HasNullableColumns = true; } col = updateColumn(col, table); // If PropertyType is empty, return null. Most likely ignoring a column due to legacy (such as OData not supporting spatial types) if (string.IsNullOrEmpty(col.PropertyType)) { return(null); } return(col); } catch (Exception ee) { throw ee; } }
/// <summary> /// 处理外键信息 /// </summary> /// <param name="fkList"></param> /// <param name="tables"></param> /// <param name="useCamelCase"></param> /// <param name="prependSchemaName"></param> /// <param name="collectionType"></param> /// <param name="checkForFkNameClashes"></param> /// <param name="includeComments"></param> public override void ProcessForeignKeys(List <ForeignKey> fkList, Tables tables, bool useCamelCase, bool prependSchemaName, string collectionType, bool checkForFkNameClashes, bool includeComments) { var constraints = fkList.Select(x => x.ConstraintName).Distinct(); foreach (var constraint in constraints) { var localConstraint = constraint; var foreignKeys = fkList.Where(x => x.ConstraintName == localConstraint).ToList(); var casete = fkList.Where(x => x.ConstraintName == localConstraint).Select(t => t.Cascade).First(); var foreignKey = foreignKeys.First(); Table fkTable = tables.GetTable(foreignKey.FkTableName, foreignKey.FkSchema); if (fkTable == null || fkTable.IsMapping || !fkTable.HasForeignKey) { continue; } Table pkTable = tables.GetTable(foreignKey.PkTableName, foreignKey.PkSchema); if (pkTable == null || pkTable.IsMapping) { continue; } var fkCols = foreignKeys.Select(x => new { fkOrdinal = x.Ordinal, col = fkTable.Columns.Find(n => n.PropertyName == x.FkColumn || n.PropertyName == x.FkColumn + "_") }) .Where(x => x != null) .ToList(); var pkCols = foreignKeys.Select(x => pkTable.Columns.Find(n => n.PropertyName == x.PkColumn)).Where(x => x != null).OrderBy(o => o.Ordinal).ToList(); if (!pkCols.Any()) { pkCols = foreignKeys.Select(x => pkTable.Columns.Find(n => n.PropertyName == x.PkColumn + "_")).Where(x => x != null).OrderBy(o => o.Ordinal).ToList(); } var fkCol = fkCols.First(); var pkCol = pkCols.First(); if (!pkCol.IsPrimaryKey) { continue; } var relationship = CodeFirstTools.CalcRelationship(pkTable, fkTable, fkCol.col, pkCol); string pkTableHumanCase = foreignKey.PkTableHumanCase(useCamelCase, prependSchemaName); string pkPropName = fkTable.GetUniqueColumnPropertyName(pkTableHumanCase, foreignKey, useCamelCase, checkForFkNameClashes, true); bool fkMakePropNameSingular = (relationship == Relationship.OneToOne); string fkPropName = pkTable.GetUniqueColumnPropertyName(fkTable.NameHumanCase, foreignKey, useCamelCase, checkForFkNameClashes, fkMakePropNameSingular); fkCol.col.EntityFk = string.Format("public virtual {0} {1} {2}{3}", pkTable.Name, pkPropName, "{ get; set; }", includeComments ? " // " + foreignKey.ConstraintName : string.Empty); string manyToManyMapping; if (foreignKeys.Count > 1) { manyToManyMapping = string.Format("c => new {{ {0} }}", string.Join(", ", fkCols.OrderBy(o => o.fkOrdinal).Select(x => "c." + x.col.PropertyName).ToArray())); } else { manyToManyMapping = string.Format("c => c.{0}", fkCol.col.PropertyName); } fkCol.col.ConfigFk = string.Format(" {0};{1}", GetRelationship(relationship, fkCol.col, pkCol, pkPropName, fkPropName, manyToManyMapping, casete), includeComments ? " // " + foreignKey.ConstraintName : string.Empty); pkTable.AddReverseNavigation(relationship, pkTableHumanCase, fkTable, fkPropName, string.Format("{0}.{1}", fkTable.Name, foreignKey.ConstraintName), collectionType, includeComments); } }
private static Column CreateColumn(IDataRecord rdr, Regex rxClean, Table table, bool useCamelCase, Regex columnFilterExclude, Func <Column, Table, Column> updateColumn) { if (rdr == null) { throw new ArgumentNullException("rdr"); } string typename = rdr["TypeName"].ToString().Trim().ToLower(); var scale = (int)rdr["Scale"]; var precision = (int)rdr["Precision"]; var col = new Column { Name = rdr["ColumnName"].ToString().Trim(), TypeName = typename, PropertyType = GetPropertyType(typename, scale, precision), MaxLength = (int)rdr["MaxLength"], Precision = precision, Default = rdr["Default"].ToString().Trim(), DateTimePrecision = (int)rdr["DateTimePrecision"], Scale = scale, Ordinal = (int)rdr["Ordinal"], IsIdentity = rdr["IsIdentity"].ToString().Trim().ToLower() == "true", IsNullable = rdr["IsNullable"].ToString().Trim().ToLower() == "true", IsStoreGenerated = rdr["IsStoreGenerated"].ToString().Trim().ToLower() == "true", IsPrimaryKey = rdr["PrimaryKey"].ToString().Trim().ToLower() == "true", PrimaryKeyOrdinal = (int)rdr["PrimaryKeyOrdinal"], IsForeignKey = rdr["IsForeignKey"].ToString().Trim().ToLower() == "true" }; if (columnFilterExclude != null && !col.IsPrimaryKey && columnFilterExclude.IsMatch(col.Name)) { col.Hidden = true; } col.IsFixedLength = (typename == "char" || typename == "nchar"); col.IsUnicode = !(typename == "char" || typename == "varchar" || typename == "text"); col.IsRowVersion = col.IsStoreGenerated && !col.IsNullable && typename == "timestamp"; if (col.IsRowVersion) { col.MaxLength = 8; } col.CleanUpDefault(); col.PropertyName = CodeFirstTools.CleanUp(col.Name); col.PropertyName = rxClean.Replace(col.PropertyName, "_$1"); // Make sure property name doesn't clash with class name if (col.PropertyName == table.NameHumanCase) { col.PropertyName = col.PropertyName + "_"; } col.PropertyNameHumanCase = (useCamelCase ? Inflector.ToTitleCase(col.PropertyName) : col.PropertyName).Replace(" ", ""); if (col.PropertyNameHumanCase == string.Empty) { col.PropertyNameHumanCase = col.PropertyName; } // Make sure property name doesn't clash with class name if (col.PropertyNameHumanCase == table.NameHumanCase) { col.PropertyNameHumanCase = col.PropertyNameHumanCase + "_"; } if (char.IsDigit(col.PropertyNameHumanCase[0])) { col.PropertyNameHumanCase = "_" + col.PropertyNameHumanCase; } if (CodeFirstTools.CheckNullable(col) != string.Empty) { table.HasNullableColumns = true; } col = updateColumn(col, table); // If PropertyType is empty, return null. Most likely ignoring a column due to legacy (such as OData not supporting spatial types) if (string.IsNullOrEmpty(col.PropertyType)) { return(null); } return(col); }
/// <summary> /// /// </summary> /// <param name="spFilterExclude"></param> /// <param name="useCamelCase"></param> /// <param name="prependSchemaName"></param> /// <param name="StoredProcedureRename"></param> /// <param name="schemaNameFilter"></param> /// <returns></returns> public override List <StoredProcedure> ReadStoredProcs(Regex spFilterExclude, bool useCamelCase, bool prependSchemaName, Func <string, string, string> StoredProcedureRename, string schemaNameFilter) { var result = new List <StoredProcedure>(); if (Cmd == null) { return(result); } Cmd.CommandText = StoredProcedureSQL + IncludeQueryTraceOn9481(); if (Cmd.GetType().Name == "SqlCeCommand") { return(result); } Cmd.CommandTimeout = 600; using (DbDataReader rdr = Cmd.ExecuteReader()) { var lastSp = string.Empty; StoredProcedure sp = null; while (rdr.Read()) { string spName = rdr["SPECIFIC_NAME"].ToString().Trim(); if (spFilterExclude != null && spFilterExclude.IsMatch(spName)) { continue; } string schema = rdr["SPECIFIC_SCHEMA"].ToString().Trim(); if (schemaNameFilter != null && !schema.Equals(schemaNameFilter, StringComparison.CurrentCultureIgnoreCase)) { continue; } if (lastSp != spName || sp == null) { lastSp = spName; sp = new StoredProcedure { Name = spName, NameHumanCase = (useCamelCase ? Inflector.ToTitleCase(spName) : spName).Replace(" ", "").Replace("$", ""), Schema = schema }; if ((string.Compare(schema, "dbo", StringComparison.OrdinalIgnoreCase) != 0) && prependSchemaName) { sp.NameHumanCase = schema + "_" + sp.NameHumanCase; } sp.NameHumanCase = StoredProcedureRename(sp.NameHumanCase, schema); result.Add(sp); } string typename = rdr["DATA_TYPE"].ToString().Trim().ToLower(); var scale = (int)rdr["NUMERIC_SCALE"]; var precision = (int)((byte)rdr["NUMERIC_PRECISION"]); var parameterMode = rdr["PARAMETER_MODE"].ToString().Trim().ToUpper(); var param = new StoredProcedureParameter { Ordinal = (int)rdr["ORDINAL_POSITION"], Mode = (parameterMode == "IN") ? StoredProcedureParameterMode.In : StoredProcedureParameterMode.InOut, Name = rdr["PARAMETER_NAME"].ToString().Trim(), SqlDbType = GetSqlDbType(typename, scale, precision), PropertyType = GetPropertyType(typename, scale, precision), DateTimePrecision = (Int16)rdr["DATETIME_PRECISION"], MaxLength = (int)rdr["CHARACTER_MAXIMUM_LENGTH"], Precision = precision, Scale = scale }; var clean = CodeFirstTools.CleanUp(param.Name.Replace("@", "")); param.NameHumanCase = Inflector.MakeInitialLower((useCamelCase ? Inflector.ToTitleCase(clean) : clean).Replace(" ", "")); if (CodeFirstTools.ReservedKeywords.Contains(param.NameHumanCase)) { param.NameHumanCase = "@" + param.NameHumanCase; } sp.Parameters.Add(param); } } return(result); }