Connecting SQL Source Control to Git in Team Foundation Service

Team Foundation Service is Microsoft’s hosted TFS, and supports both Git and TFS source control.  TFS(ervice) is free for teams up to five, and all repos are private.  If you need a Team Foundation Service account, go to http://tfs.visualstudio.com and log in with your Microsoft ID.  If you’re using Git, you’ll also need to create an alternate set of credentials to connect to the repo.

In SQL Source Control, Git is now a top-level provider, but full Git support hasn’t been implemented yet (Subversion and TFS have much better support in the current version, 3.4 at the time of this post).  For the current version of SQL Source Control, you’ll still need to switch to your favorite Git tool for add/commit/push.  Upcoming features in SQL Source Control for Git include better branching support and support for migrations.  Migrations allow you to alter schema objects without dropping them first—like changing the name of a table without dropping it first—as well as seeding initial data.

1. Create project in TFS

image

 

2. Navigate to Code tab, clone the repo in your favorite Git tool using the URL provided.  TFS only supports HTTPS right now, so you need a set of alternate credentials to use Git.

image

image

 

3. In SSMS, right-click the database you want to put under source control and select “Link database to source control”.

image

 

4. Then, browse to your working folder and select whether each developer will have their own copy of the database, or everyone will work from one central database.

image

 

5. Once the database has been linked, click on the “Commit Changes” tab and choose “Save Changes”.  For a Git repo, this just saves the script files—you still need to do an add, commit and push in your favorite tool.

image

 

6. Once you’ve done an add/commit/push, you can log into TFS again and use all the functionality of diffs, history tracking, etc.  Your other team members can pull from this repo and use SQL Source Control to easily keep their instances up to date.

TryParse() in one line–when to use it, when to avoid it

Note: The code samples shown below are meant to run in LinqPad as “C# Statements”. You can use the free version, but it’s well worth paying for.

Almost all types (every one I can think of, but I’m not going to commit and say “all”) have both a .Parse() and .TryParse() method, the differences between which are discussed at http://stackoverflow.com/questions/467613/parse-v-tryparse. As a general rule, we try and use .TryParse() everywhere.

The one down side to .TryParse() is that it requires a little extra code–an output variable, and a result variable, and you’ll probably need to set a default value in case the parsing fails. You can accomplish this in one line of code with the right syntax that at first doesn’t look like it should work.

Here’s an example of how to do .TryParse() in one line, showing a syntax which works and one which doesn’t (.Dump() is a method specific to LinqPad).

string _int = "8675309";

int i1 = int.TryParse(_int, out i1)
	? i1
	: 0;
i1.Dump();

Output: 8675309

//This doesn't work
//var i2 = int.TryParse(_int, out i2)
//	? i2
//	: 0;
//i2.Dump();

It’s interesting how the explicitly typed variable works, but the implicitly typed one doesn’t. The same thing happens with a GUId:

string _guid = "d09eccda-533a-4772-b589-dbc5676fb690";

//This works
Guid g1 = Guid.TryParse(_guid, out g1) 
	? g1 
	: Guid.Empty;
g1.Dump();

output: d09eccda-533a-4772-b589-dbc5676fb690

//This does not:
//var g2 = Guid.TryParse(_guid.ToString(), out g2)
// 	? g2
// 	: Guid.Empty;
//g2.Dump();

So we know implicit typing isn’t going to work. Are there any other places we’ve found you need to be careful? Yes, one more so far–Booleans. Based on the patterns above, you’d expect this to work:

string _bool = "false";
bool b1 = bool.TryParse(_bool, out b1);
b1.Dump();

output: true

Go try that in LindPad and see what happens. Spoiler alert: b1 is true, not false. The result of .TryParse() is a Boolean, and instead of assigning the output value to b1, the result is being assigned to b1. Instead, you need to use the longer syntax to make Booleans work correctly:

string _bool = "false";
bool b2;
bool b3 = bool.TryParse(_bool, out b2);
b2.Dump();
b3.Dump();

output: true
false

That will end up with the correct values assigned.

So there you have it–how to handle a .TryParse() in one line, and a couple of pitfalls in doing so. Hope that helps!