I’ve written several blogs and community samples on working with SSAS Projects directly using AMO (instead of SSAS Databases on an Analysis Services server). I was travelling this weekend, and got a chance to create a sample MSBuild task that will generate a .ASDatabase file directly from a Visual Studio project, without requiring Visual Studio itself. This means that multiple developers can work on a project, check-in files via source control, and can schedule an automated build, build on a dedicated “clean” machine (without VS), or any of a number of other scenarios.
I added the custom MSBuild task to the Analysis Services Community Samples project on CodePlex under the SsasHelper sample.
The Build task code itself is trivial. I won’t go into a lot of detail on that, has creating/debugging custom tasks is well documented (you can start the library with MSBuild.exe as the external program and the project file as the argument). I used it as a wrapper for previously developed ProjectHelper code that does all the heavy lifting. All we do is inherit from Microsoft.Build.Utilities.Task and implement the Execute method. All I do in the task is de-serialize the project (based on the Visual Studio project passed in), validate the project (based on the target version of SSAS), and write out the .ASDatabase file. This could of course be modified to use another method to deploy the database, but I’ve been using the .ASDatabase method for awhile with no issues.
Here’s the main code for the method:
try { Database database = ProjectHelper.DeserializeProject(SsasProjectFile); // ... Verify our project doesn't have any errors ... ValidationResultCollection results; bool isValidated = ProjectHelper.ValidateDatabase(database, SsasServerEdition, out results); // If the database doesn't validate (i.e., a build error) // log the errors and return failure. foreach (ValidationResult result in results) { Log.LogError(result.Description); } if (!isValidated) { return false; } // Build the .ASDatabase file ProjectHelper.GenerateASDatabaseFile(database, SsasTargetFile); } catch (Exception ex) { Log.LogErrorFromException(ex); return false; }
return true;
So… how do we actually use this? I included a sample project file in the SsasBuilder project. The basic idea is you have a project file (a file that ends in “.[optional prefix]proj”, such as “.proj”, “.csproj”, etc.). You can call this via MSBuild. Note that the standard SSAS project file DOES NOT work with MSBuild. The schemas required for that project conflict with the MSBuild schema, so you’ll have to create another project file, or build the build step into somewhere else. Here’s an example project file:
1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2: <UsingTask TaskName="SsasBuilder.SsasBuildASDatabaseFileTask"
3: AssemblyFile="C:TFSSsasHelperSsasBuilderbindebugSsasBuilder.dll"/>
4: <Target Name="BuildASDatabaseFile">
5: <SsasBuildASDatabaseFileTask SsasProjectFile = "C:Testenterprise_GoldAdventure Works DW 2008.dwproj"
6: SsasTargetFile = "C:TestSsasBuildTestAdventureWorks.ASDtabase"
7: SsasServerEdition = "Enterprise" />
8: </Target>
9: </Project>
Here I’m using absolute paths, but you can use either properties or relative paths as required for your particular project. You just use a UsingTask tag to point to the assembly containing the build task, then use the task in a target. For this sample I’m I’m taking the SSAS project file and target filename, along with the server edition, as parameters. If there are no errors in the project file, the .ASDatabase file will be generated in the specified location.
Now, all you have to do is call “MSBuild.exe <Whateveryounamedyourproject>”, and you’ll get a .ASDatabase file out of it…
Cheers,
David