2016-11-01 9 views
0

私はデータベースをc#で別のデータベースにコピーします。データベースのコピー後にテーブルを更新できません

すべては大丈夫です。私は行を挿入しようとすると、

はしかし、私はこのエラーを取得する:

System.Data.SqlClient.SqlException:INSERT権限はオブジェクト・データベース・スキーマ「DBO」で拒否されました。

これは、データベースをコピーするには、私のC#のコードです:

public bool CreateDataBase(string dbName) 
{   
     //var connstring = "data source=.;initial catalog=InformedWorker;integrated security=True;"; 
     var connstring = "Server=localhost;Integrated security=SSPI;database=master"; 
     var localhost = "localhost"; 

     try 
     { 
      Server server = new Server(localhost); 



      Microsoft.SqlServer.Management.Smo.Database sourceDatabase = server.Databases["InformedWorkerTemplate"]; 

      Microsoft.SqlServer.Management.Smo.Database newDatbase = new Microsoft.SqlServer.Management.Smo.Database(server, dbName); 


      var clientDBPath = ConfigurationManager.AppSettings["ClientData"]; 


      newDatbase.FileGroups.Add(new FileGroup(newDatbase, "PRIMARY")); 
      DataFile dtPrimary = new DataFile(newDatbase.FileGroups["PRIMARY"], "PriValue", clientDBPath + "\\" + dbName + ".mdf"); 
      dtPrimary.Size = 77.0 * 1024.0; 
      dtPrimary.GrowthType = FileGrowthType.KB; 
      dtPrimary.Growth = 1.0 * 1024.0; 

      newDatbase.FileGroups["PRIMARY"].Files.Add(dtPrimary); 

      LogFile logFile = new LogFile(newDatbase, "Log", clientDBPath + "\\" + dbName + ".ldf"); 
      logFile.Size = 7.0 * 1024.0; 
      logFile.GrowthType = FileGrowthType.Percent; 
      logFile.Growth = 10.0; 

      newDatbase.LogFiles.Add(logFile); 

      newDatbase.Create(); 

      Transfer transfer = new Transfer(sourceDatabase); 
      transfer.CopySchema = true; 
      transfer.CopyData = true; 
      transfer.Options.DriAllKeys = true; 
      transfer.CopyAllObjects = true; 
      transfer.CopyAllViews = true; 
      transfer.CopyAllDatabaseTriggers = true; 
      transfer.CopyAllDefaults = true; 
      transfer.CopyAllFullTextCatalogs = true; 
      transfer.CopyAllFullTextStopLists = true; 
      transfer.CopyAllPartitionFunctions = true; 
      transfer.CopyAllPartitionSchemes = true; 
      transfer.CopyAllPlanGuides = true; 
      transfer.CopyAllRoles = true; 
      transfer.CopyAllRules = true; 
      transfer.CopyAllSchemas = true; 
      transfer.CopyAllSearchPropertyLists = true; 
      transfer.CopyAllSequences = true; 
      transfer.CopyAllSqlAssemblies = true; 
      transfer.CopyAllStoredProcedures = true; 
      transfer.CopyAllSynonyms = true; 
      transfer.CopyAllTables = true; 
      transfer.CopyAllUserDefinedAggregates = true; 
      transfer.CopyAllUserDefinedDataTypes = true; 
      transfer.CopyAllUserDefinedFunctions = true; 
      transfer.CopyAllUserDefinedTableTypes = true; 
      transfer.CopyAllUserDefinedTypes = true; 
      transfer.CopyAllUsers = true; 
      transfer.CopyAllViews = true; 
      transfer.CopyAllXmlSchemaCollections = true; 
      transfer.CopyAllObjects = true; 
      transfer.Options.WithDependencies = true; 
      transfer.DestinationDatabase = newDatbase.Name; 
      transfer.CopySchema = true; 
      transfer.CopyData = true; 
      transfer.Options.DriAllKeys = true; 

      StringCollection transferScript = transfer.ScriptTransfer(); 

      using (SqlConnection conn = new SqlConnection(connstring)) 
      { 
       conn.Open(); 
       using (SqlCommand switchDatabase = new SqlCommand("USE [" + newDatbase.Name + "]", conn)) 
       { 
        switchDatabase.ExecuteNonQuery(); 
       } 

       foreach (string scriptLine in transferScript) 
       { 
        using (SqlCommand scriptCmd = new SqlCommand(scriptLine, conn))//, transaction)) 
        { 
         int res = scriptCmd.ExecuteNonQuery(); 
        } 
       } 
      } 

      return true; 
     } 
     catch (Exception ex) 
     { 
      logging.AddError(ex.ToString()); 
     } 
     return false; 
    } 

これは、行を追加するために自分のサーバー/ APIコードです(私は、私はデータベースを変更Enitity枠組みに自分のDBを結合した)

public void Exchange() 
    { 
     try 
     { 
      var query = admin.Subscriptions.Where(d => d.CompanyRef == "56f55e3e-deac-4cde-ae4b-83671363a54e").FirstOrDefault(); 
      if (query != null) 
      { 
       o.Database.Connection.Open(); 
       o.Database.Connection.ChangeDatabase(query.DatabaseName); 
       o.Customers.Add(new Customer() 
       { 
        CompanyName = "CompanyName", 
        CompanyRef = "CompanyRef", 
        CustomerRef = "CustomerRef", 
        DOE = DateTime.Now, 
        Email = "Email", 
        FName = "FName", 
        MobileNo = "MobileNo", 
        Salutation = "Salutation", 
        ServerRef = "ServerRef", 
        ServerTS = DateTime.Now, 
        SName = "SName", 
        TelephoneNo = "TelephoneNo", 
        Active = true 


       }); 
       o.SaveChanges(); 
      } 
     } 
     catch (Exception ex) 
     { 
      logging.AddError(ex.ToString()); 
     } 
    } 

私はDBからDBにすべてをコピーするので、他に何ができるのかわかりません。

+0

あなたは別のサーバー – TheGameiswar

+0

にそれを復元する@TheGameiswarこんにちは。いいえ、自分のローカルサーバーにすべてではありません –

+0

コピーは、DBと同じ役割と特権を取得するのと同じと仮定しました。このようなコマンドはDBAが最善の方法で処理し、カプセル化する必要があるため、C#の使用は避けてください。 –

答えて

0

私はこれが私が必要としていたよりも難しくしているようです。

これはDBA機能に関する他のポスターに同意しますが、管理コードでこれを行う必要がありました。

また、ロスブッシュ(+1)のおかげで、どこを見ても私にスターターをくれました。しかし、私はこれらのユーザーがすでに新しいデータベースにコピーされていると言わなければなりません。それは持ち越されなかったユーザーへのマッピング許可でした。

答えは簡単だった:

var localhost = "localhost"; 
Server srv = new Server(localhost); 
Database sourceDatabase = srv.Databases["1407245195"]; 
var username = @"IIS APPPOOL\DefaultAppPool"; 
srv.Databases["1407245195"].Roles["db_accessadmin"].AddMember(username); 
srv.Databases["1407245195"].Roles["db_backupoperator"].AddMember(username); 
srv.Databases["1407245195"].Roles["db_datareader"].AddMember(username); 
srv.Databases["1407245195"].Roles["db_datawriter"].AddMember(username); 
srv.Databases["1407245195"].Roles["db_ddladmin"].AddMember(username); 
srv.Databases["1407245195"].Roles["db_owner"].AddMember(username); 
srv.Databases["1407245195"].Roles["db_securityadmin"].AddMember(username); 
+0

Sysデータテーブルから読み取るために利用したアクセス方法に注意してください。どんなアカウントが使われても、サーバーには多くのパワーがあり、外部の影響からガードしカプセル化する必要があります。これは、アクセスでアカウントに偽装する機能を削除する点でprocsを使用する主な理由です。 –

+0

@clifton_hありがとう。私はそれがどのように妥協するかを見ることができます。このコードは、このタイプのデータベースのこの1つのサーバー用です。ストアドプロシージャを使用してC#から呼び出せば、まだ妥協ではないでしょうか?私は考えてくれてありがとう:) –

+0

Np。コマンドのストリーム上で良好な暗号化を仮定します。 SQL Serverでは、役割と権限をきめ細かく設定できます。 'GRANT EXECUTE ON TO 'という特権を持つシェルログインを作成します。さらに良いことに、 'EXECUTE AS 'という序文でストアドプロシージャを実行してください。 (注意:sysadminを使用するロールはほぼ常に必要なものではなく、避けてください)これはサーバレベルで検証されます。今、あなたはどのようにしてどこにアクセスするのかをもっと明白にすることができます。あなたのDBAがあなたを助けることができるべき他の解決策があります。乾杯。 –

2

あなたのユーザーや権限をスクリプトする必要があります。サーバーまたはインスタンスレベルでセキュリティを適用する場合は、SQL Serverユーザーのアクセス権とアクセス権を、作成したデータベースコピーに付与する必要があります。

あなたはほとんどそこにいます。

Managing Users, Roles and Logins

あなたはとても適切な注意を取るようにしてください、あなたのコード内でユーザーの資格情報にアクセスする必要があるとしています。

+0

ありがとう、私はこのplsを実装することができますので、サンプルC#コードを提供できますか? –

+0

これを実行する1つの方法は、SQL Server Management StudioでSQLコマンドを作成してアクセス許可を割り当て、コピーされたデータベースで動作することをテストし、コードが既にいくつかの場所で実行されているために "SqlCommand"しかし、やはり、この種のタスクは、すべてが単一のストアドプロシージャに入れられるためにはるかに適しており、テストとメンテナンスがより簡単になります。 –

+0

SMOドキュメントを追加しました。 –

関連する問題