Automatyczne wgranie bazy danych podczas uruchomienia MS Tests

Odpowiedz Nowy wątek
2014-10-13 19:53
0

Witam,
potrzebuje tak skonfigurować uruchomienie testów(MS Tests) aby przed ich wykonaniem projekt bazodanowy został wgrany na serwer. W jaki sposób można takie coś zrealizować? W załączniku przesyłam projekt który przedstawia problem.



Pozostało 580 znaków

2014-10-13 22:47

Wrzuć dacpaca przy użyciu SqlPackage.exe


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."

Pozostało 580 znaków

2014-10-15 19:28
0

Bardzo fajnie działa ten SqlPackage.exe, jedynie jest problem aby plik dacpac był kopiowany do folderu output. Na razie ten problem rozwiązałem poprzez wejście do folderu projektu bazy danych. Czy znasz może jakiś sposób aby to objeść? Kod wygląda tak:

public class DacpacPublish
{
    public DacpacPublish(string projectName)
    {
        ProjectName = projectName;
        OutputFileName = string.Format("{0}.dacpac", projectName);
        PublishProfileName = string.Format("{0}.dacpac.dev.publish.xml", projectName);
        SqlPackagePath = @"C:\Program Files (x86)\Microsoft SQL Server\120\DAC\bin\SqlPackage.exe";
    }

    public string ProjectName { get; set; }

    public string OutputFileName { get; set; }

    public string PublishProfileName { get; set; }

    public string SqlPackagePath { get; set; }

    public void Publish()
    {
        var startInfo = new ProcessStartInfo
        {
            FileName = SqlPackagePath,
            Arguments = CreateArguments(),
            RedirectStandardError = true,
            UseShellExecute = false
        };
        using (Process process = Process.Start(startInfo))
        {
            string error = process.StandardError.ReadToEnd();
            process.WaitForExit();
        }
    }

    private string CreateArguments()
    {
        string dacpacPath = GetDacpacPath();
        ThrowIfFilesNotExits(dacpacPath);
        return string.Format(@"/Action:Publish /SourceFile:{0} /Profile:{1}", dacpacPath, PublishProfileName);
    }

    private void ThrowIfFilesNotExits(string dacpacPath)
    {
        if (!File.Exists(dacpacPath))
        {
            throw new FileNotFoundException("Dacpac file not exists", dacpacPath);
        }
        if (!File.Exists(PublishProfileName))
        {
            throw new FileNotFoundException("Publish profile not exits", PublishProfileName);
        }
        if (!File.Exists(SqlPackagePath))
        {
            throw new FileNotFoundException("SqlPackage not exists", SqlPackagePath);
        }
    }

    private string GetDacpacPath()
    {
        if (File.Exists(OutputFileName))
        {
            return OutputFileName;
        }
        else
        {
            string executablePath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            string solutionPath = Path.GetFullPath(Path.Combine(executablePath, @"../../../"));
            return string.Format(@"{0}\{1}\bin\{2}\{3}",
                solutionPath, ProjectName, GetBuildFolderName(), OutputFileName);
        }
    }

    private string GetBuildFolderName()
    {
        string path = "Debug";
        #if (!DEBUG)
        path = "Release";
        #endif
        return path;
    }
}


edytowany 1x, ostatnio: Bumcykowy, 2014-10-15 19:29

Pozostało 580 znaków

2014-10-16 12:54
0

Nie wiem czy dobrze rozumiem problem, ale w ustawieniach projektu w Visual Studio można ustawić Build output path.


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."

Pozostało 580 znaków

2014-10-16 21:10
0

Właśnie nie chciał bym w projekcie takiego czegoś zmieniać, udało mi się to objeść za pomocą xcopy. Zamieszczam moje aktualne rozwiązanie, może komuś się przyda.

/// <summary>
/// The class is used to publish database project to Sql Server from test project. 
/// Files "#DbProjectName.dacpac" and "#DbProjectName.dacpac.dev.publish.xml" have to be 
/// in test project output folder. To copy a file, you can use "Post-build event command line" 
/// using following command:
///  IF EXIST "$(SolutionDir)#ProjectName\$(OutDir)#ProjectName.dacpac" (
///      xcopy "$(SolutionDir)#ProjectName\$(OutDir)#ProjectName.dacpac" "$(TargetDir)" /y
///  )
/// </summary>
public class DbPublish
{
    private readonly string sqlPackagePath = GetSqlPackagePath();
    private readonly int timeoutDelay = 60000; // 60 sec
    private readonly string sourceName;
    private readonly string profileName; 
    private string connectionString;

    public DbPublish(string dbProjectName)
    {
        sourceName = string.Format("{0}.dacpac", dbProjectName);
        profileName = string.Format("{0}.dacpac.dev.publish.xml", dbProjectName);
    }

    public string ConnectionString
    {
        get
        {
            if (connectionString == null)
            {
                connectionString = ReadConnectionStringFromPublishProfile();
            }
            return connectionString;
        }
    }

    private string ReadConnectionStringFromPublishProfile()
    {
        if (!File.Exists(profileName))
        {
            throw new FileNotFoundException("Publish profile not exits", profileName);
        }
        XDocument doc = XDocument.Parse(File.ReadAllText(profileName));
        XNamespace ns = @"http://schemas.microsoft.com/developer/msbuild/2003";
        var values = (
            from pg in doc.Descendants(ns + "PropertyGroup")
            select new
            {
                ConnectionString = pg.Element(ns + "TargetConnectionString").Value,
                DbName = pg.Element(ns + "TargetDatabaseName").Value
            }).Single();
        return string.Format("{0};Initial Catalog={1}", values.ConnectionString, values.DbName);
    }

    public void Publish()
    {
        ThrowIfFileNotExits();

        using (Process process = RunSqlPublish())
        {
            string error = process.StandardError.ReadToEnd();
            if (error.Length > 0)
            {
                throw new InvalidOperationException(error);
            }
            if (!process.WaitForExit(timeoutDelay))
            {
                process.Kill();
                throw new TimeoutException("SqlPacakge.exe exceeded timeout.");
            }
        }
    }

    private void ThrowIfFileNotExits()
    {
        if (!File.Exists(sourceName))
        {
            throw new FileNotFoundException("Dacpac file not exists", sourceName);
        }
        if (!File.Exists(profileName))
        {
            throw new FileNotFoundException("Publish profile not exits", profileName);
        }
        if (!File.Exists(sqlPackagePath))
        {
            throw new FileNotFoundException("SqlPackage not exists", sqlPackagePath);
        }
    }

    private Process RunSqlPublish()
    {
        var startInfo = new ProcessStartInfo
        {
            FileName = sqlPackagePath,
            Arguments = CreateSqlPublishArguments(),
            RedirectStandardError = true,
            UseShellExecute = false
        };
        return Process.Start(startInfo);
    }

    private string CreateSqlPublishArguments()
    {
        return string.Format(@"/Action:Publish /SourceFile:{0} /Profile:{1}", 
            sourceName, profileName);
    }

    private static string GetSqlPackagePath()
    {
        string programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
        return string.Format(@"{0}\{1}", programFiles, @"Microsoft SQL Server\110\DAC\bin\SqlPackage.exe");
    }
}


Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0