如何基于Microsoft.SqlServer.Management.Smo.Transfer中的模式名称复制表

Hem*_*ote 5 c# sql sql-server smo

我从Source_Test数据库Destination_Test数据库复制表.

Microsoft.SqlServer.Management.Smo.Transfer.

它复制了所有表格 from Source_Test to Destination_Test

但我想要有架构'TestSchema'的表.

主要问题是,它复制了所有表dbo schema.即使我设置 this.CopyAllTables = false;它仍然复制它.如何限制它.我试过以下:

public class CopyTable : Transfer, ISchemaCopy
{
   private void CopyTables()
   {
      this.CopyAllTables = false;
      var server = new Server(new ServerConnection(connection));
      var script = this.ScriptTransfer().Cast<string>();
   }
}
Run Code Online (Sandbox Code Playgroud)

DWr*_*ght 2

我认为下面的代码可以实现您想要实现的目标。如果通过提供 SchemaName 将其设置为仅从一个架构复制表,则它将仅添加该架构的表进行复制。

关键是构建您想要复制的表的集合,并将该集合显式添加到 ObjectList。不要忘记将 ServerName 和 DatabaseName 更改为真实的名称。

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;

/* Needs references to:
 * 
 * System.Data
 * Microsoft.SqlServer.ConnectionInfo 
 * Microsoft.SqlServer.Management.Sdk.Sfc
 * Microsoft.SqlServer.Smo
 * Microsoft.SqlServer.SmoExtended
 */

namespace CopyTablesExample
{
    class Program
    {
        public class CopyTables : Transfer
        {
            public string SchemaName { get; set; }
            public string DatabaseName { get; set; }
            public string ServerName { get; set; }


            public IEnumerable<string> GetScript()
            {
                //This is what we will return
                IEnumerable<string> scriptStrings = null;

                if (this.DatabaseName == null) {
                    throw new Exception("DatabaseName property not set.");
                }

                if (this.ServerName == null) {
                    throw new Exception("ServerName property not set.");
                }

                var server = new Server(new ServerConnection(ServerName));
                this.Database = server.Databases[this.DatabaseName];

                //Turn off all objects.  Below we will start turning on what we want.
                //You may wish to add more object types.
                this.CopyAllObjects = false;

                if (this.SchemaName == null) {
                    //No schema means all tables
                    this.CopyAllTables = true;
                }
                else {
                    //A specific schema means all tables from that schema
                    this.CopyAllTables = false;
                    //We only want to copy tables in a specific schema.
                    List<Table> tablesToCopy = new List<Table>();
                    foreach (Table t in this.Database.Tables) {
                        if (t.Schema.Equals(this.SchemaName)) {
                            tablesToCopy.Add(t);
                        }
                    }

                    //Add specifically the tables we want which are from the schema we want
                    this.ObjectList.AddRange(tablesToCopy);
                }

                try {
                    scriptStrings = this.ScriptTransfer().Cast<string>();
                }
                catch (Exception ex) {
                    Console.WriteLine("We got an exception.");
                    throw;
                }
                return scriptStrings;
            }
        }

        static void Main(String[] Args)
        {
            //Only set a SchemaName in line below, when you want to restrict yourself to copying that schema's tables.
            CopyTables ct = new CopyTables() { ServerName = "xyz", DatabaseName = "abc", SchemaName = "junk" } ; 
            var copyTablesScript = ct.GetScript();

            //For validation, display the script as generated
            foreach (var item in copyTablesScript) {
                Console.WriteLine(item);
            }
            var discard = Console.ReadKey();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)