using Microsoft.Data.SqlClient; using Microsoft.SqlServer.Management.Smo; using DBMigration.Models; using System.Threading.Tasks; namespace DBMigration.Services { public class DatabaseService { public async IAsyncEnumerable GetTables(ConnectionInfo connection) { await foreach (var obj in GetDatabaseObjectsAsync(connection, "TABLE")) { yield return obj; } } public async IAsyncEnumerable GetViews(ConnectionInfo connection) { await foreach (var obj in GetDatabaseObjectsAsync(connection, "VIEW")) { yield return obj; } } public async IAsyncEnumerable GetProcedures(ConnectionInfo connection) { await foreach (var obj in GetDatabaseObjectsAsync(connection, "PROCEDURE")) { yield return obj; } } private async IAsyncEnumerable GetDatabaseObjectsAsync(ConnectionInfo connection, string objectType) { using (var conn = new SqlConnection(connection.GetConnectionString())) { await conn.OpenAsync(); var server = new Server(new Microsoft.SqlServer.Management.Common.ServerConnection(conn)); var database = server.Databases[connection.DatabaseName]; switch (objectType) { case "TABLE": foreach (Table table in database.Tables) { if (table.IsSystemObject || table.Name.StartsWith("_")) continue; yield return CreateDatabaseObject(table); await Task.Yield(); } break; case "VIEW": foreach (Microsoft.SqlServer.Management.Smo.View view in database.Views) { if (view.IsSystemObject) continue; yield return CreateDatabaseObject(view); await Task.Yield(); } break; case "PROCEDURE": foreach (StoredProcedure sp in database.StoredProcedures) { if (sp.IsSystemObject) continue; yield return CreateDatabaseObject(sp); await Task.Yield(); } break; } } } private DatabaseObject CreateDatabaseObject(Table table) { return new DatabaseObject { Name = table.Name, Schema = table.Schema, Type = "TABLE", Definition = GetTableDefinition(table) }; } private DatabaseObject CreateDatabaseObject(Microsoft.SqlServer.Management.Smo.View view) { return new DatabaseObject { Name = view.Name, Schema = view.Schema, Type = "VIEW", Definition = view.TextBody }; } private DatabaseObject CreateDatabaseObject(StoredProcedure sp) { return new DatabaseObject { Name = sp.Name, Schema = sp.Schema, Type = "PROCEDURE", Definition = sp.TextBody }; } private string GetTableDefinition(Table table) { var options = new ScriptingOptions { IncludeIfNotExists = true, ScriptDrops = false, WithDependencies = true, Indexes = true, Triggers = true, ClusteredIndexes = true, NonClusteredIndexes = true }; return table.Script(options).ToString(); } } }