Search code examples
c#smo

Modifying the DefaultConstraintName property of the Column object is not allowed


I am trying to work with the official Microsoft.SqlServer.SharedManagementObjects NuGet package on an old project which was working just fine with SMO 2014. When I try to add or edit the default value for a column I wrote the following:

var server = new Server("(local)");

var database = new Database(server, "test_db");
database.Create();

var table = new Table(database, "test_tbl");

var columnKey = new Column(table, "key", DataType.Int);
columnKey.Identity = true;
columnKey.IdentitySeed = 0;
columnKey.IdentityIncrement = 1;
table.Columns.Add(columnKey);

var columnVal = new Column(table, "val", DataType.Int);
columnVal.AddDefaultConstraint("defVal").Text = "1";
table.Columns.Add(columnVal);

table.Create();

columnVal.DefaultConstraint.Drop();
columnVal.Refresh();

columnVal.AddDefaultConstraint("defVal").Text = "2";
columnVal.Alter();

database.Drop();

The last Alter() on the Column instance throws an exception:

System.InvalidOperationException : Microsoft SMO failed during commit: Microsoft.SqlServer.Management.Smo.FailedOperationException: Alter failed for Column 'val'. ---> Microsoft.SqlServer.Management.Smo.SmoException: Modifying the DefaultConstraintName property of the Column object is not allowed. You must drop and recreate the object with the desired property.

The "DefaultConstraintName" property did not exist in 2016 SMO's (according to the official documentation). Is it a SMO's bug or is there anything else I can do?


Solution

  • Ok, so here is the answer: adding a default constraint on a COLUMN requires the TABLE to be altered, not the column so, instead of calling columnVal.Alter() I needed to call table.Alter(). Now that I think about this, it seems kind of obvious because when you need to add a default constraint you actually would use this SQL command:

    ALTER TABLE [test_tbl]
        ADD CONSTRAINT [defVal] DEFAULT ((2)) FOR [val]
    

    As usual, Microsoft frameworks/libraries give shitty information about what is really happening (see the message of the exception which is thrown). I hope this is useful to someone else.