C#使用microsoft.sqlserver.management.smo恢复数据库5(访问被拒绝)

时间:2017-03-17 12:59:00

标签: c# sql-server-2016 smo

我正在尝试使用Microsoft.SqlServer.Management.Smo恢复数据库,但我一直收到访问被拒绝的错误。

我已为实例(MSSQL$LOCAL2016)设置了服务用户,并具有该文件夹的完全访问权限。

该文件夹是该实例的默认文件夹(尽管在我转移到制作时不能说同样的文件夹。)

我在C#

中创建文件夹
rstDatabase.SqlRestore(sqlServer);

因错误而失败:

  

操作系统返回错误' 5(访问被拒绝。)'在尝试RestoreContainer :: ValidateTargetForCreation' on' C:\ Database \ Rates.setuptest \ Data'。
  文件' RateUploader'无法恢复到' C:\ Database \ Rates.setuptest \ Data'。使用WITH MOVE标识文件的有效位置   操作系统返回错误' 5(访问被拒绝。)'在尝试RestoreContainer :: ValidateTargetForCreation' on' C:\ Database \ Rates.setuptest \ Logs'。
  文件' RateUploader_log'无法恢复到' C:\ Database \ Rates.setuptest \ Logs'。使用WITH MOVE标识文件的有效位置   在规划RESTORE语句时发现了问题。以前的消息提供了详细信息   RESTORE DATABASE异常终止。

我已经更改了文件夹权限,甚至允许每个人'完全访问

我已将服务登录更改为本地服务并允许访问本地目录

我是新鲜的想法

这是代码,但它非常标准

    public static IEnumerable<RestoreDatabaseResponse> RestoreDatabase(String databaseName)
    {
        var eventQueue = new Queue<RestoreDatabaseResponse>();
        var counter = 0;

        MySqlConnectionStringBuilder stringBuilder = new MySqlConnectionStringBuilder(ConfigurationManager.ConnectionStrings["adminSqlAccess"].ConnectionString);

        string serverName = stringBuilder.Server, userName = stringBuilder.UserID, password = stringBuilder.Password, 
            pFileLocation = string.Format(ConfigurationManager.AppSettings["dbPath"], databaseName, "Data"), 
            lFileLocation = string.Format(ConfigurationManager.AppSettings["dbPath"], databaseName, "Logs"),
            bakFileLocation = ConfigurationManager.AppSettings["bakDbPath"];

        //permisions are propagating
        if (!Directory.Exists(pFileLocation))
            Directory.CreateDirectory(pFileLocation);
        if (!Directory.Exists(lFileLocation))
            Directory.CreateDirectory(lFileLocation);

        ServerConnection connection = new ServerConnection(serverName, userName, password);
        Server sqlServer = new Server(connection);
        Restore rstDatabase = new Restore();

        //recently added events for reporting.  Still fails without these two
        rstDatabase.Complete += (sender, args) =>
        {
            eventQueue.Enqueue(new RestoreDatabaseResponse
            {
                Command = $"Restore {databaseName}",
                Status = ResponseStatus.Success,
                Detail = "Complete",
                Index = counter++,
                PercentComplete = 100
            });
        };

        rstDatabase.PercentComplete += (sender, args) =>
        {
            eventQueue.Enqueue(new RestoreDatabaseResponse
            {
                Command = $"Restore {databaseName}",
                Status = ResponseStatus.PartialSuccess,
                Detail = "Running",
                Index = counter++,
                PercentComplete = args.Percent
            });
        };

        rstDatabase.Action = RestoreActionType.Database;
        rstDatabase.Database = $"Rates.{databaseName}";

        // I even tried skipping this step.  Still error
        rstDatabase.RelocateFiles.Add(new RelocateFile("RateUploader", pFileLocation));
        rstDatabase.RelocateFiles.Add(new RelocateFile("RateUploader_log", lFileLocation));

        BackupDeviceItem bkpDevice = new BackupDeviceItem(bakFileLocation, DeviceType.File);
        rstDatabase.Devices.Add(bkpDevice);
        rstDatabase.ReplaceDatabase = true;
        RestoreDatabaseResponse errorResponse = null;

        try
        {
            rstDatabase.SqlRestore(sqlServer);
        }
        catch (Exception exception)
        {
            errorResponse = new RestoreDatabaseResponse
            {
                Command = $"Restore {databaseName}",
                Status = ResponseStatus.Failure,
                Detail = exception,
                Index = counter++,
                PercentComplete = 0
            };
        }

        if (errorResponse != null)
        {
            yield return errorResponse;
            yield break;
        }

        while (true)
        {
            if (!eventQueue.Any())
                Thread.Sleep(100);
            else
            {
                var e = eventQueue.Dequeue();
                yield return e;

                if(e.Status== ResponseStatus.Success)
                    yield break;
            }
        }
    }

1 个答案:

答案 0 :(得分:1)

哦,为了皮特的缘故!

我从重定位路径&gt; _&lt;

中省略了文件名

公平地说,“移动”确实意味着从一个文件夹移动到另一个文件夹,错误信息也与大多数人似乎遇到的权限问题相同