I found a bug in datadude yesterday and, with a little help, I was able to come up with a workaround so figured I'd post here in case anyone else comes up against it.
In the RTM version of Datadude it is possible to specify the name of the database when it is deployed. As you can see here:

Note the specified name of the database and the name of the Datadude project that are circled.
If you do a build of your datadude project from within Visual Studio then the resultant .sql file will contain something like the following at the top of it:
1 :setvar databasename "MyExampleDatabase"
2 USE [master]
3 GO
4
5 :on error exit
6
7 IF ( DB_ID(N'$(databasename)') IS NOT NULL
8 AND DATABASEPROPERTYEX(N'$(databasename)','Status') <> N'ONLINE')
9 BEGIN
10 RAISERROR(N'The state of the target database, %s, is not set to ONLINE. To deploy to this database, its state must be set to ONLINE.', 16, 127,N'$(databasename)') WITH NOWAIT
11 RETURN
12 END
13 GO
14
15 :on error resume
16
17 CREATE DATABASE [$(databasename)] COLLATE SQL_Latin1_General_CP1_CS_AS
18 GO
However, there's a problem. If you have your database builds integrated into TFS Team Build the name of the database will not appear in the script, instead you will get the default database name which is the name of your project. So it'll look something like this:
1 :setvar databasename "datadudetmp"
2 USE [master]
3 GO
4
5 :on error exit
6 ...
7 ...
8 <snip>
Note how the name of the database is different - its the same as the name of the project as you can see in the screenshot.
I spoke to Jamie Laflen about the problem. Jamie is one of the developers of Datadude and he confirmed that this is a bug. He also told me WHY it is a bug. If you check out the .user file that is in the project root folder you will see something like the following:
1 <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <PropertyGroup Condition=" '$(Configuration)' == 'Default' ">
3 <TargetDatabase>MyExampleDatabase</TargetDatabase>
4 </PropertyGroup>
5 <PropertyGroup>
6 <DesignDBName>datadudetmp_DB_43fe3dd4-1ffa-4d51-9192-881f8660573d</DesignDBName>
7 </PropertyGroup>
8 </Project>
You can see that on line 3 that the name of the database is defined in this file. It is NOT defined in the .dbproj file. If you look inside there you'll see the following for the <TargetDatabase> element
<TargetDatabase>
</TargetDatabase>
Its not defined! The bug, in a nutshell, is that the Datadude targets file overwrites the setting in the .dbproj file. It creates a problem because the build process checks the following places for the <TargetDatabase> setting:
- Project File (i.e. .dbproj file)
- Datadude targets file
- Common targets
- .user file
And that is the order in which it checks them so essentially the last one wins. When you build from the Visual Studio IDE it works but when you build from TFSBuild it doesn't because the .user file is not used during TFS builds.
Happily there is an easy fix - it just requires a manual edit of the .dbproj file. There are two steps though:
- Fill in the name of the database in the <TargetDatabase> element
- Move that element to a property group after the import of the Datadude targets file
In other words, you need to modify your .dbproj file to make it look like this:
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v8.0\TeamData\Microsoft.VisualStudio.TeamSystem.Data.Tasks.targets" />
<PropertyGroup Condition=" '$(Configuration)' == 'Default' ">
<TargetDatabase>MyExampleDatabase</TargetDatabase>
</PropertyGroup>
<ItemGroup>
That's it! That's all you need to do. Hope this helps.
Thank you to Jamie Laflen for taking the time to help me out with this. He tells me that this bug will be fixed in an upcoming version of Datadude. The fix is that the targets file only overwrites the <TargetDatabase> setting if it is not defined in the .dbproj file. This means that you will not have to move <TargetDatabase>MyExampleDatabase</TargetDatabase> to after the import directive.
However, you will still have to define the database name manually inthe .dbproj file - it is not set according to the value entered in the Build properties (as per the screenshot above). That didn't seem right to me to and I asked Jamie (there's too many Jamie's in this blog post :) what the rationale for that was. Here is his answer:
The idea was that there are a set of build properties that are relevant to a user’s sandbox environment and not to the team as a whole; for example, the target connection string and designdb name. You could argue that the target database does not fall into this sandbox category, and this argument does make sense for TFS.
This is an area where we could certainly use feedback from our customers. Is the sandboxing mechanism completely unknown and everyone just standardizes on a deployment target, or are customers checking in the .user file (oy – I hope not!). Do customers actually use different solution configurations, or, does everyone just stick with “Default.”
So, the datadude team are looking for feedback on this behaviour. Feel free to submit your feedback as a comment on this blog and I shall collate them and feedback to Jamie. Otherwise, contact the datadude team through the usual channels:
-Jamie