简体   繁体   中英

How to modify the DACPAC model at build time?

I want to alter the table model during build time in my BuildContributor . Here is some sample code:

using Microsoft.SqlServer.Dac.Deployment;
using Microsoft.SqlServer.Dac.Extensibility;
using Microsoft.SqlServer.Dac.Model;
using System.Collections.Generic;
using System.Linq;

namespace MyNamespace
{
    [ExportBuildContributor("MyNamespace.MyBuildContributor", "1.0.0.0")]
    public class MyBuildContributor : BuildContributor
    {
        protected override void OnExecute(BuildContributorContext context, IList<ExtensibilityError> messages)
        {
            foreach (var table in context.Model.GetObjects(DacQueryScopes.UserDefined, ModelSchema.Table))
            {
                var tableName = table.Name.Parts.Last();
                var rowId = "alter table " + tableName + " add rowid uniqueidentifier";
                context.Model.AddObjects(rowId);
            }
        }
    }
}

The build succeeds with no errors but I don't see rowid in any of the tables when I go look in the model.xml file in bin\\Debug\\MyDb.dacpac .

You can't use Model.AddObjects in this context.

Model.AddObjects from ( https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.dac.model.tsqlmodel.addobjects(v=sql.120).aspx#M:Microsoft.SqlServer.Dac.Model.TSqlModel.AddObjects(System.String) ):

"Adds objects to the model based on the contents of a TSql Script string. The script should consist of valid TSql DDL statements. Objects added using this method cannot be updated or deleted at a later point as update/delete requires a script name to be specified when adding the objects. If this is a requirement use the AddOrUpdateObjects method instead."

IE it can only add objects like tables or stored procedure, columns by themselves aren't added to the model.

If you want to update an existing object (ie to add a column to an existing table) you will need to use "TSqlModel.AddOrUpdateObjects" which also takes a script name. You can get the script name from a build contributor by using:

var sourceName = table.GetSourceInformation().SourceName;

Then you can build the updated script you want (just a rough outline of rebuilding the SQL for stack overflow, I'm sure you can do better):

var sql = table.GetScript();
sql = sql.Trim().TrimEnd(')', ';') + ", rowid uniqueidentifier);";

var sourceName = table.GetSourceInformation().SourceName;
model.AddOrUpdateObjects(sql, sourceName, new TSqlObjectOptions());

There are a few ways you could create your new script but basically what you need is a new script which has your extra column and the original table definition which you can pass to AddorUpdateObjects to overwrite the original create table statement.

If you don't get a source to use in AddorUpdateObjects then maybe you could use a post-deploy script to add it to any table you need and then use a deployment contributor to remove the drop column step.

You could also look at using a deployment contributor instead to add the new column step to that.

Hope it helps! Let me know how you get on :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM