DacSamples Moves from CodePlex to GitHub

The DacSamples project is moving from CodePlex to GitHub under the new name /Microsoft/DACExtensions/. As part of the move the team is adding a new extension to the DacFx API to allow easier usage of the public model.

Licensing

The new GitHub project, Microsoft/DACExtensions, is licensed under the MIT License as this is the preferred license for new GitHub projects in the Microsoft GitHub Organization. For those wanting to use the existing code under the existing Apache 2.0 license, the DacSamples CodePlex project will be left up, however, all new additions will only be added to the GitHub project.

Extended Public Model

We have receive lots of feedback about the usability and discoverability of the existing public API. The overwhelming sentiment is that the current API, which is very similar to using reflection in .Net, is too cumbersome to use and the notion of Referenced and Referencing relationships is difficult to understand. The good news is the metadata provided by the public API has most of the information needed to create a strongly-type API. To demonstrate the richness of the model metadata, we have created a set of T4 templates that generate a strongly-typed API so it can be easily incorporated into custom Deployment Contributors (DeploymentPlanModifier) as well as custom Source Code Analysis Rules (SqlCodeAnalysisRule) or other customer applications.

The new strongly-typed model provides much better discoverability and aligns better with model API designs. Along with the strongly-typed properties and references the strongly-type API provides interfaces for each SQL Server version allowing users to program against a specific SQL Server version like SQL Server 2014 or Microsoft Azure SQLDB. The following examples illustrate how to use the new strongly-typed API as well as leverage the version specific interfaces:

 

Existing API Usage:

TSqlModelmodel = new TSqlModel(SqlServerVersion.Sql120, new TSqlModelOptions(){});

 

// Create the Identifier for the dbo.users table

ObjectIdentifier tableId = new ObjectIdentifier("dbo", "users");

 

// Query the model for the dbo.users table

// Note the return type is the generic TSqlObject not a Table object

TSqlObject table = model.GetObject(Table.TypeClass, tableId, DacQueryScopes.UserDefined);

 

// Get all the columns that do not support NULL values

IEnumerable<TSqlObject> column = table

.GetReferenced(Table.Columns)

// Note the use of GetProperty and the explicity cast

.Where(c =>!((bool)c.GetProperty(Column.Nullable)));

 

New Strongly-Typed API Usage:

 

TSqlTypedModel model = new TSqlTypedModel(SqlServerVersion.Sql120, new TSqlModelOptions() { });

 

// Create the Identifier for the dbo.users table

ObjectIdentifier tableId = new ObjectIdentifier("dbo", "users");

 

// Query the model for the dbo.users table

// Note that the return type is TSqlTable not TSqlObject

TSqlTable table = model.GetObject<TSqlTable>(tableId, DacQueryScopes.UserDefined);

 

// Get all the columns that do not support NULL values

// Note the Columns reference property that returns an

// IEnumerable<TSqlColumn>

//

// Note the Nullable property on the TSqlColumn to access

// the Boolean value Nullable.

IEnumerable<TSqlColumn> column = table.Columns.Where(c =>!c.Nullable);

 

Version Specific Interfaces.

The new interfaces for each SQL Server version allows programming against the correct set of properties and relationships for a target SQL Server version. The ISql90TSqlLogin and ISqlAzureTSqlLogin interfaces illustrate well the differences in surface area between different platforms:

SQL Server 2005

SQL Azure

public interface ISql90TSqlLogin : ISqlModelElement

{

Boolean CheckExpiration

{

get;

}

Boolean CheckPolicy

{

    get;

}

String DefaultDatabase

{

    get;

}

String DefaultLanguage

{

    get;

}

Boolean Disabled

{

    get;

}

LoginEncryptionOption EncryptionOption

{

    get;

}

Boolean MappedToWindowsLogin

{

    get;

}

String Password

{

    get;

}

Boolean PasswordHashed

{

    get;

}

Boolean PasswordMustChange

{

    get;

}

String Sid

{

    get;

}

IEnumerable<ISql90TSqlAsymmetricKey> AsymmetricKey

{

    get;

}

IEnumerable<ISql90TSqlCertificate> Certificate

{

    get;

}

IEnumerable<ISql90TSqlCredential> Credential

{

    get;

}

}

public interface ISqlAzureTSqlLogin : ISqlModelElement

{        

Boolean Disabled

{

get;

}

String Password

{

get;

}

}

 

These version specific interfaces allow consumers to leverage compile time validation and IntelliSense for specific versions of SQL Server.

TSqlTypedModel model = new TSqlTypedModel(SqlServerVersion.Sql90, new TSqlModelOptions() { });

 

// Create Identifier for the l1 login

ObjectIdentifier loginId = new ObjectIdentifier("l1");

 

// Get the login from the model

TSqlLogin login = model.GetObject<TSqlLogin>(loginId, DacQueryScopes.UserDefined);

 

// Downcast login to ISql90TSqlLogin to ensure only

// SQL 2005 properties

// and references are used

ISql90TSqlLogin sql90Login = (ISql90TSqlLogin)login;

 

// Downcast login to ISqlAzureTSqlLogin to ensure only

// Microsoft Azure SQLDB properties

// and references are used

ISqlAzureTSqlLogin sqlAzureLogin = (ISqlAzureTSqlLogin)login;

Future Plans

This project will be a vehicle for sharing examples of using the extensibility APIs. The main focus of future additions we be addressing customer pain points we see through the forum and other customer engagements. We look forward to your feedback on examples that will help to better understanding DacFx extensibility and the platform as a whole.

Contact Us

The development team would really like to hear your feedback on this project. For issues and Design Change Requests (DCR) please use the issue tracker. For general questions and help using the public APIs or SQL Server Data Tools please use the team's MSDN forum: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/home?forum=ssdt.