So I've been playing around with MS TFS at work, setting up new user defined fields (UDFs) for work item types. The way that TFS handles it is that it doesn't really store metadata in the way I'm describing it. This makes it possible to create UDFs that are not consistent from project to project (although it does do some validation when you try to do that) and it's hard to query from the back end.

TFS supports UDFs on the work items (bugs, features, tasks, user stories, backlog items, etc.) It allows you to define these UDFs by adding them to the work item template XML and giving them a reference name (i.e. Microsoft.VSTS.Scheduling.OriginalEstimate)

You are not supposed to query TFS from the back end, except through the data warehouse. The warehouse holds rows for each work item along with a column for each UDF on a work item. There will be one column for all work items across all projects and collections for each given data item, i.e.??Microsoft.VSTS.Scheduling.OriginalEstimate will only have one column in the warehouse work item tables (Dimension or Fact).

The TFS database stores the work item ID, the UDF column ID, and the value in a value column for either int, string, date, etc. The data is then copied into the warehouse for easy querying. TFS creates an MS SQL Server database per collection (which is a grouping of projects).

I have no idea how TFS manages the metadata internally, but it appears to be a hodge podge. ??It seems to be very robust in adding, validating, and deleting these UDFs when they are assigned to work item types throughout the projects and collections. For example, if you add a new reference name (i.e. henrylafleur.com.MyValue), then it will automatically add this as a column in the warehouse for querying.

You can query the warehouse through SQL, through Reporting Services, or through the TFS front end. It gives you a consistent way to get at your data using various methods.

Overall, I find the TFS user defined fields to be easy to use, but too easy to get wrong. The performance so far is excellent. There are too many times that you have to copy/paste reference names or just type them in. They have to be entered exactly and then mapped to the correct name. But because it's a bunch of developers using it, we can deal with it. We deal with the same things in our code, but VS.NET gives us Intellisense for that.