Im doing some automation and in the middle of rewriting some 10-15 old, quirky scripts to one single and simple unit, which can:
Im doing this using the Microsoft.SqlServer.Dac in which i can export/import dac packs.
It works nicely :), but after doing all my TDD and testing, it was time for the real thing and it turns out I had completely missed that we have 2 domains at my work.
This means I get an error when I'm importing the dacpac in the dev environment, due to the fact that our 2 domains do not have full 2 way trust and of course the database has users from both domains. In particular the production domain users. I can see 3 viable solutions:
Ive read the documentation (which is vague of course), trying to find a set of options which could achieve 2) or 3). Ive testet a lot of combos but none that will work. The dac pac import keeps trying to create the users and fails since the production users cannot be verified in the dev environment.
Im using Deploy and Extract to export/import. The different options can be found here:
No combination I have found works and Ive even read posts that suggest that its a bug in the DacPac. But I'm not sure. A last option I'm looking into right now is to use the GenerateScript method which hopefully can force to exclusion of users/logins, but I fear that its not going to work either. See (http://technet.microsoft.com/en-us/library/hh753526.aspx).
Question: How can I exclude users/logins from my dacpac, either in the export or the import?
UPDATE
Current Extract Settings:
IgnoreUserLoginMappings = true,
VerifyExtraction = false,
Current Deploy Settings:
CreateNewDatabase = true,
DeployDatabaseInSingleUserMode = true,
DisableAndReenableDdlTriggers = true,
IgnoreUserSettingsObjects = true,
Update
So far everything points to one ugly solution.
I can generate a deploy script using DacServices.
Then i can parse the script (Remove logins etc).
Then write the result to a file.
And then call SQLCMD in an external process given it the generated and parsed file.
Finally i must evaluate the result from the SQLCMD process.
The reason for the use of SQLCMD is that the generated script apperently not is pure tsql, but uses stuff as ':setvar', which only SQLCMD can handle, as far as i can tell. Come on MS...
Again if anyone know a better way to do this in C#, or know of a bug fix/update for the DacPac assemblies, please share. :)
Update
I found that stuff like IgnorePartitionSchemes also do not work. It seems that the namespace Microsoft.SqlServer.Dac, is not just a little but VERY buggy or lacking implementation.
I managed to solve this problem with the following deployment of a dacpac
file. The important setting was in ExcludeObjectTypes
.
const string connectionString = @"Data Source=(LocalDB)\MSSQLLocalDB...";
var dacServices = new DacServices(connectionString);
// show deployment in the output window.
dacServices.Message += (o, args) => Debug.WriteLine(args.Message);
dacServices.ProgressChanged += (o, args) => Debug.WriteLine(args.Status);
// load the file.
var dacpac = DacPackage.Load("file.dacpac");
var options = new DacDeployOptions
{
IgnorePermissions = true,
IgnoreUserSettingsObjects = true,
IgnoreLoginSids = true,
IgnoreRoleMembership = true,
// THIS IS THE MAGIC SETTING THAT FINALLY WORKED.
ExcludeObjectTypes = new[] {
ObjectType.Users,
ObjectType.Logins,
ObjectType.RoleMembership }
};
dacServices.Deploy(
dacpac,
"MyDbName",
true,
options);