Last active
August 29, 2015 14:25
-
-
Save fabiomaulo/7625df3974fb7cba2022 to your computer and use it in GitHub Desktop.
NHibernate Extensions to autocreate indexes fot FK and clustered indexes for tables without PK
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class NHibernateConfigurationExtensions | |
{ | |
private static readonly PropertyInfo tableMappingsProperty = typeof (Configuration).GetProperty("TableMappings", | |
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); | |
private static readonly FieldInfo indexesField = typeof (Table).GetField("indexes", | |
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); | |
public static void CreateIndexesForForeignKeys(this Configuration configuration, | |
Func<string, bool> includeTablePredicate) | |
{ | |
configuration.BuildMappings(); | |
var tables = (ICollection<Table>) tableMappingsProperty.GetValue(configuration, null); | |
foreach (var table in tables.Where(x => includeTablePredicate(x.Name))) | |
{ | |
var columnsOfPk = table.HasPrimaryKey ? table.PrimaryKey.Columns.Select(x => x.Name).ToArray() : new string[0]; | |
foreach (var foreignKey in table.ForeignKeyIterator) | |
{ | |
if (table.HasPrimaryKey) | |
{ | |
var columnsOfFk = foreignKey.Columns.Select(x => x.Name).ToArray(); | |
var fkHasSameColumnsOfPk = !columnsOfPk.Except(columnsOfFk).Concat(columnsOfFk.Except(columnsOfPk)).Any(); | |
if (fkHasSameColumnsOfPk) | |
{ | |
continue; | |
} | |
} | |
var idx = new Index(); | |
idx.AddColumns(foreignKey.Columns); | |
idx.Name = "IX" + foreignKey.Name.Substring(2); | |
idx.Table = table; | |
table.AddIndex(idx); | |
} | |
} | |
} | |
public static void CreateIndexesForForeignKeys(this Configuration configuration) | |
{ | |
CreateIndexesForForeignKeys(configuration, x=> true); | |
} | |
public static void AddClusteredIndexesWhereNeeded(this Configuration configuration) | |
{ | |
string defaultCatalog = PropertiesHelper.GetString(Environment.DefaultCatalog, configuration.Properties, null); | |
string defaultSchema = PropertiesHelper.GetString(Environment.DefaultSchema, configuration.Properties, null); | |
var dialect = Dialect.GetDialect(configuration.Properties); | |
var tables = (ICollection<Table>) tableMappingsProperty.GetValue(configuration, null); | |
foreach (var table in tables) | |
{ | |
var indexes = (Dictionary<string, Index>) indexesField.GetValue(table); | |
if (table.HasPrimaryKey || indexes.Count != 1) | |
{ | |
continue; | |
} | |
Index lonelyIndex = indexes.First().Value; | |
indexes.Clear(); | |
var clusteredIndexCreateSql = SqlCreateClusteredIndexString(dialect, lonelyIndex.Name, table, lonelyIndex.ColumnIterator, defaultCatalog, defaultSchema); | |
var indexDropSql = lonelyIndex.SqlDropString(dialect, defaultCatalog, defaultSchema); | |
var indexDbObject = new SimpleAuxiliaryDatabaseObject(clusteredIndexCreateSql, indexDropSql); | |
configuration.AddAuxiliaryDatabaseObject(indexDbObject); | |
} | |
} | |
private static string SqlCreateClusteredIndexString(Dialect dialect, string name, Table table, | |
IEnumerable<Column> columns, string defaultCatalog, string defaultSchema) | |
{ | |
StringBuilder buf = new StringBuilder("CREATE CLUSTERED INDEX ") | |
.Append(dialect.QualifyIndexName ? name : StringHelper.Unqualify(name)) | |
.Append(" ON ") | |
.Append(table.GetQualifiedName(dialect, defaultCatalog, defaultSchema)) | |
.Append(" (") | |
.Append(string.Join(", ", columns.Select(x=> x.GetQuotedName(dialect)))) | |
.Append(")"); | |
return buf.ToString(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment