From 3a92c26a7fefef81eefbf8dab2bbdf5f12737c20 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 12 Mar 2014 17:17:52 +1100 Subject: [PATCH 1/5] Adds ability to extract index details from databases using sql syntax provider. --- .../AdditionalIndexesAndKeys.cs | 14 +++++++---- .../SqlSyntax/ISqlSyntaxProvider.cs | 3 +++ .../SqlSyntax/MySqlSyntaxProvider.cs | 25 +++++++++++++++++++ .../SqlSyntax/SqlCeSyntaxProvider.cs | 10 ++++++++ .../SqlSyntax/SqlServerSyntaxProvider.cs | 14 +++++++++++ .../SqlSyntax/SqlSyntaxProviderBase.cs | 2 ++ 6 files changed, 63 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs index 1998770bec..a5e99bd607 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs @@ -1,5 +1,6 @@ using System; using Umbraco.Core.Configuration; +using Umbraco.Core.Persistence.Migrations.Initial; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero { @@ -7,11 +8,14 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero public class AdditionalIndexesAndKeys : MigrationBase { public override void Up() - { - //Create.Index("IX_umbracoNodeTrashed").OnTable("umbracoNode").OnColumn("trashed").Ascending().WithOptions().NonClustered(); - //Create.Index("IX_cmsContentVersion_ContentId").OnTable("cmsContentVersion").OnColumn("ContentId").Ascending().WithOptions().NonClustered(); - //Create.Index("IX_cmsDocument_published").OnTable("cmsDocument").OnColumn("published").Ascending().WithOptions().NonClustered(); - //Create.Index("IX_cmsDocument_newest").OnTable("cmsDocument").OnColumn("newest").Ascending().WithOptions().NonClustered(); + { + var dbSchema = new DatabaseSchemaCreation(Context.Database); + var schemaResult = dbSchema.ValidateSchema(); + + Create.Index("IX_umbracoNodeTrashed").OnTable("umbracoNode").OnColumn("trashed").Ascending().WithOptions().NonClustered(); + Create.Index("IX_cmsContentVersion_ContentId").OnTable("cmsContentVersion").OnColumn("ContentId").Ascending().WithOptions().NonClustered(); + Create.Index("IX_cmsDocument_published").OnTable("cmsDocument").OnColumn("published").Ascending().WithOptions().NonClustered(); + Create.Index("IX_cmsDocument_newest").OnTable("cmsDocument").OnColumn("newest").Ascending().WithOptions().NonClustered(); } public override void Down() diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs index c62fa1a923..b4c0020305 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs @@ -59,9 +59,12 @@ namespace Umbraco.Core.Persistence.SqlSyntax bool SupportsClustered(); bool SupportsIdentityInsert(); bool? SupportsCaseInsensitiveQueries(Database db); + IEnumerable GetTablesInSchema(Database db); IEnumerable GetColumnsInSchema(Database db); IEnumerable> GetConstraintsPerTable(Database db); IEnumerable> GetConstraintsPerColumn(Database db); + + IEnumerable> GetDefinedIndexes(Database db); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs index 0b8d80a21f..97e94457b8 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs @@ -115,6 +115,31 @@ namespace Umbraco.Core.Persistence.SqlSyntax return list; } + public override IEnumerable> GetDefinedIndexes(Database db) + { + List> list; + try + { + var indexes = + db.Fetch(@"SELECT DISTINCT + TABLE_NAME, INDEX_NAME, COLUMN_NAME, CASE NON_UNIQUE WHEN 1 THEN 0 ELSE 1 END AS `UNIQUE` +FROM INFORMATION_SCHEMA.STATISTICS +WHERE TABLE_SCHEMA = @TableSchema +ORDER BY TABLE_NAME, INDEX_NAME", + new { TableSchema = db.Connection.Database }); + list = + indexes.Select( + item => + new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME, item.UNIQUE)) + .ToList(); + } + finally + { + db.CloseSharedConnection(); + } + return list; + } + public override bool DoesTableExist(Database db, string tableName) { long result; diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs index d9e9599dab..769d5547f4 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs @@ -226,6 +226,16 @@ namespace Umbraco.Core.Persistence.SqlSyntax indexItem.INDEX_NAME))).ToList(); } + public override IEnumerable> GetDefinedIndexes(Database db) + { + var items = + db.Fetch( + "SELECT TABLE_NAME, INDEX_NAME, COLUMN_NAME, [UNIQUE] FROM INFORMATION_SCHEMA.INDEXES ORDER BY TABLE_NAME, INDEX_NAME"); + return + items.Select( + item => new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME, item.UNIQUE)); + } + public override bool DoesTableExist(Database db, string tableName) { var result = diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs index 4046a7575d..07c1d97c7e 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs @@ -151,6 +151,20 @@ namespace Umbraco.Core.Persistence.SqlSyntax return items.Select(item => new Tuple(item.TABLE_NAME, item.COLUMN_NAME, item.CONSTRAINT_NAME)).ToList(); } + public override IEnumerable> GetDefinedIndexes(Database db) + { + var items = + db.Fetch( + @"select T.name as TABLE_NAME, I.name as INDEX_NAME, AC.Name as COLUMN_NAME, +CASE WHEN I.is_unique_constraint = 1 OR I.is_unique = 1 THEN 1 ELSE 0 END AS [UNIQUE] +from sys.tables as T inner join sys.indexes as I on T.[object_id] = I.[object_id] + inner join sys.index_columns as IC on IC.[object_id] = I.[object_id] and IC.[index_id] = I.[index_id] + inner join sys.all_columns as AC on IC.[object_id] = AC.[object_id] and IC.[column_id] = AC.[column_id] +order by T.name, I.name"); + return items.Select(item => new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME, item.UNIQUE)).ToList(); + + } + public override bool DoesTableExist(Database db, string tableName) { var result = diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs index 004aabfc70..1ceeddafb7 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs @@ -212,6 +212,8 @@ namespace Umbraco.Core.Persistence.SqlSyntax return new List>(); } + public abstract IEnumerable> GetDefinedIndexes(Database db); + public virtual bool DoesTableExist(Database db, string tableName) { return false; From 3aadca167f23bd4f37562945ad4f67ab22a648f0 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 12 Mar 2014 18:00:00 +1100 Subject: [PATCH 2/5] oops, updated the reset to resetcollections for clearing collections for resolvers. --- .../ObjectResolution/ApplicationEventsResolver.cs | 4 ++-- src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Core/ObjectResolution/ApplicationEventsResolver.cs b/src/Umbraco.Core/ObjectResolution/ApplicationEventsResolver.cs index 3d1d44133b..a31598bfc8 100644 --- a/src/Umbraco.Core/ObjectResolution/ApplicationEventsResolver.cs +++ b/src/Umbraco.Core/ObjectResolution/ApplicationEventsResolver.cs @@ -80,7 +80,7 @@ namespace Umbraco.Core.ObjectResolution public void Dispose() { - Reset(); + ResetCollections(); } } @@ -141,7 +141,7 @@ namespace Umbraco.Core.ObjectResolution private void DisposeResources() { _legacyResolver.Dispose(); - Reset(); + ResetCollections(); } } diff --git a/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs b/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs index 3ada10333c..d6ea1b3967 100644 --- a/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs +++ b/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs @@ -340,7 +340,7 @@ namespace Umbraco.Core.ObjectResolution /// WARNING! Do not use this unless you know what you are doing, clear all types registered and instances /// created. Typically only used if a resolver is no longer used in an application and memory is to be GC'd /// - internal void Reset() + internal void ResetCollections() { using (new WriteLock(_lock)) { From d0fc3ddba5dc9ee198c8b0280c1d84413dfaaf80 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 12 Mar 2014 18:11:05 +1100 Subject: [PATCH 3/5] ensures applicationeventsresolver is disposed of in the correct place. --- src/Umbraco.Core/CoreBootManager.cs | 3 --- src/Umbraco.Core/UmbracoApplicationBase.cs | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Core/CoreBootManager.cs b/src/Umbraco.Core/CoreBootManager.cs index eb57c41354..add9b65fce 100644 --- a/src/Umbraco.Core/CoreBootManager.cs +++ b/src/Umbraco.Core/CoreBootManager.cs @@ -219,9 +219,6 @@ namespace Umbraco.Core // we're ready to serve content! ApplicationContext.IsReady = true; - //And now we can dispose of our startup handlers - save some memory - ApplicationEventsResolver.Current.Dispose(); - return this; } diff --git a/src/Umbraco.Core/UmbracoApplicationBase.cs b/src/Umbraco.Core/UmbracoApplicationBase.cs index dd6c3a8103..c861eca6cd 100644 --- a/src/Umbraco.Core/UmbracoApplicationBase.cs +++ b/src/Umbraco.Core/UmbracoApplicationBase.cs @@ -5,6 +5,7 @@ using System.Web.Mvc; using StackExchange.Profiling; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; +using Umbraco.Core.ObjectResolution; namespace Umbraco.Core { @@ -40,6 +41,9 @@ namespace Umbraco.Core .Initialize() .Startup(appContext => OnApplicationStarting(sender, e)) .Complete(appContext => OnApplicationStarted(sender, e)); + + //And now we can dispose of our startup handlers - save some memory + ApplicationEventsResolver.Current.Dispose(); } /// From aee10348e5f3c73bb7848d84f656a00a018d93b1 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 12 Mar 2014 18:37:22 +1100 Subject: [PATCH 4/5] Ensures not to add new indexes if they already exist --- .../DbIndexDefinition.cs | 13 +++++++++++ .../Initial/DatabaseSchemaCreation.cs | 10 ++++++++ .../Initial/DatabaseSchemaResult.cs | 2 ++ .../AdditionalIndexesAndKeys.cs | 23 +++++++++++++++---- .../SqlSyntax/MySqlSyntaxProvider.cs | 2 +- .../SqlSyntax/SqlCeSyntaxProvider.cs | 2 +- .../SqlSyntax/SqlServerSyntaxProvider.cs | 3 ++- src/Umbraco.Core/Umbraco.Core.csproj | 1 + 8 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DbIndexDefinition.cs diff --git a/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DbIndexDefinition.cs b/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DbIndexDefinition.cs new file mode 100644 index 0000000000..e495d61550 --- /dev/null +++ b/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DbIndexDefinition.cs @@ -0,0 +1,13 @@ +namespace Umbraco.Core.Persistence.DatabaseModelDefinitions +{ + /// + /// Represents a database index definition retreived by querying the database + /// + internal class DbIndexDefinition + { + public virtual string IndexName { get; set; } + public virtual string TableName { get; set; } + public virtual string ColumnName { get; set; } + public virtual bool IsUnique { get; set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs index 53f1938c00..398b36e43c 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs @@ -125,6 +125,16 @@ namespace Umbraco.Core.Persistence.Migrations.Initial { var result = new DatabaseSchemaResult(); + //get the db index defs + result.DbIndexDefinitions = SqlSyntaxContext.SqlSyntaxProvider.GetDefinedIndexes(_database) + .Select(x => new DbIndexDefinition() + { + TableName = x.Item1, + IndexName = x.Item2, + ColumnName = x.Item3, + IsUnique = x.Item4 + }).ToArray(); + foreach (var item in OrderedTables.OrderBy(x => x.Key)) { var tableDefinition = DefinitionFactory.GetTableDefinition(item.Value); diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaResult.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaResult.cs index c70eb820b8..968acfc4bd 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaResult.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaResult.cs @@ -29,6 +29,8 @@ namespace Umbraco.Core.Persistence.Migrations.Initial public List ValidConstraints { get; set; } + internal IEnumerable DbIndexDefinitions { get; set; } + /// /// Determines the version of the currently installed database. /// diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs index a5e99bd607..f1f7f6c043 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Umbraco.Core.Configuration; using Umbraco.Core.Persistence.Migrations.Initial; @@ -12,10 +13,24 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero var dbSchema = new DatabaseSchemaCreation(Context.Database); var schemaResult = dbSchema.ValidateSchema(); - Create.Index("IX_umbracoNodeTrashed").OnTable("umbracoNode").OnColumn("trashed").Ascending().WithOptions().NonClustered(); - Create.Index("IX_cmsContentVersion_ContentId").OnTable("cmsContentVersion").OnColumn("ContentId").Ascending().WithOptions().NonClustered(); - Create.Index("IX_cmsDocument_published").OnTable("cmsDocument").OnColumn("published").Ascending().WithOptions().NonClustered(); - Create.Index("IX_cmsDocument_newest").OnTable("cmsDocument").OnColumn("newest").Ascending().WithOptions().NonClustered(); + //do not create any indexes if they already exist in the database + + if (schemaResult.DbIndexDefinitions.Any(x => x.IndexName == "IX_umbracoNodeTrashed") == false) + { + Create.Index("IX_umbracoNodeTrashed").OnTable("umbracoNode").OnColumn("trashed").Ascending().WithOptions().NonClustered(); + } + if (schemaResult.DbIndexDefinitions.Any(x => x.IndexName == "IX_cmsContentVersion_ContentId") == false) + { + Create.Index("IX_cmsContentVersion_ContentId").OnTable("cmsContentVersion").OnColumn("ContentId").Ascending().WithOptions().NonClustered(); + } + if (schemaResult.DbIndexDefinitions.Any(x => x.IndexName == "IX_cmsDocument_published") == false) + { + Create.Index("IX_cmsDocument_published").OnTable("cmsDocument").OnColumn("published").Ascending().WithOptions().NonClustered(); + } + if (schemaResult.DbIndexDefinitions.Any(x => x.IndexName == "IX_cmsDocument_newest") == false) + { + Create.Index("IX_cmsDocument_newest").OnTable("cmsDocument").OnColumn("newest").Ascending().WithOptions().NonClustered(); + } } public override void Down() diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs index 97e94457b8..b1554045f0 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs @@ -130,7 +130,7 @@ ORDER BY TABLE_NAME, INDEX_NAME", list = indexes.Select( item => - new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME, item.UNIQUE)) + new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME, item.UNIQUE == 1)) .ToList(); } finally diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs index 769d5547f4..a0acd8a8a8 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs @@ -233,7 +233,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax "SELECT TABLE_NAME, INDEX_NAME, COLUMN_NAME, [UNIQUE] FROM INFORMATION_SCHEMA.INDEXES ORDER BY TABLE_NAME, INDEX_NAME"); return items.Select( - item => new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME, item.UNIQUE)); + item => new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME, item.UNIQUE == 1)); } public override bool DoesTableExist(Database db, string tableName) diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs index 07c1d97c7e..00311d6af6 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs @@ -161,7 +161,8 @@ from sys.tables as T inner join sys.indexes as I on T.[object_id] = I.[object_id inner join sys.index_columns as IC on IC.[object_id] = I.[object_id] and IC.[index_id] = I.[index_id] inner join sys.all_columns as AC on IC.[object_id] = AC.[object_id] and IC.[column_id] = AC.[column_id] order by T.name, I.name"); - return items.Select(item => new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME, item.UNIQUE)).ToList(); + return items.Select(item => new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME, + item.UNIQUE == 1)).ToList(); } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 98a2aab8b9..db16a05848 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -211,6 +211,7 @@ + From 3b268344842b4cd44c5acf8b3b2006bf2b83fd8f Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 12 Mar 2014 18:40:39 +1100 Subject: [PATCH 5/5] updates migration to make it a little faster --- .../AdditionalIndexesAndKeys.cs | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs index f1f7f6c043..884829affc 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs @@ -1,7 +1,9 @@ using System; using System.Linq; using Umbraco.Core.Configuration; +using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Migrations.Initial; +using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero { @@ -10,24 +12,31 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero { public override void Up() { - var dbSchema = new DatabaseSchemaCreation(Context.Database); - var schemaResult = dbSchema.ValidateSchema(); + + var dbIndexes = SqlSyntaxContext.SqlSyntaxProvider.GetDefinedIndexes(Context.Database) + .Select(x => new DbIndexDefinition() + { + TableName = x.Item1, + IndexName = x.Item2, + ColumnName = x.Item3, + IsUnique = x.Item4 + }).ToArray(); //do not create any indexes if they already exist in the database - if (schemaResult.DbIndexDefinitions.Any(x => x.IndexName == "IX_umbracoNodeTrashed") == false) + if (dbIndexes.Any(x => x.IndexName == "IX_umbracoNodeTrashed") == false) { Create.Index("IX_umbracoNodeTrashed").OnTable("umbracoNode").OnColumn("trashed").Ascending().WithOptions().NonClustered(); } - if (schemaResult.DbIndexDefinitions.Any(x => x.IndexName == "IX_cmsContentVersion_ContentId") == false) + if (dbIndexes.Any(x => x.IndexName == "IX_cmsContentVersion_ContentId") == false) { Create.Index("IX_cmsContentVersion_ContentId").OnTable("cmsContentVersion").OnColumn("ContentId").Ascending().WithOptions().NonClustered(); } - if (schemaResult.DbIndexDefinitions.Any(x => x.IndexName == "IX_cmsDocument_published") == false) + if (dbIndexes.Any(x => x.IndexName == "IX_cmsDocument_published") == false) { Create.Index("IX_cmsDocument_published").OnTable("cmsDocument").OnColumn("published").Ascending().WithOptions().NonClustered(); } - if (schemaResult.DbIndexDefinitions.Any(x => x.IndexName == "IX_cmsDocument_newest") == false) + if (dbIndexes.Any(x => x.IndexName == "IX_cmsDocument_newest") == false) { Create.Index("IX_cmsDocument_newest").OnTable("cmsDocument").OnColumn("newest").Ascending().WithOptions().NonClustered(); }