Monday, April 19, 2010

SP 2010 - Managed Metadata Columns ARE Supported in LINQ to SharePoint

I apparently spoke too soon! You can get to Managed Metadata Columns in LINQ to SharePoint with SPMetal, just not directly off the command line. You need to supply a parameters option.

First you'll want to create your parameters file. I've found two different ways to get the Managed Metadata Column to show up. The first attempt I used this XML in my parameter file.


  
    
      
    
  



I saved this file to metaloptions.xml and then ran the following command.

SPMetal.exe /web:http://mysite /code:SPMySite.cs /namespace:SPMySite /parameters:metaloptions.xml

The output of that command will include a warning, but it seems to have no impact on LINQ working. I think it's purely informational and not relevant to what we are working with.

Warning: All content types for list Form Templates were excluded.

Now when I query with LINQ I see the hidden fields that power my Managed Metadata Column, which look familiar.

On my typed list item object, I now had three new fields:
  • Specialty_0 - String
  • TaxonomyCatchAllColumnCatchAllData - IList
  • TaxonomyCatchAllColumnId - IList

Those fields hold values that look like this, respectively. Unfortunately, this isn't terribly useful.
  • Value One|e203149a-6852-46fb-9d8e-9c21d350068d
  • z4KDDWMtIUSjerk4bQvlyA==|0c7eej633Ee2lYK7KOL0jw==|mhQD4lJo+0adjpwh01AGjQ==
  • 4

I tried another pass on my parameters file. This time I used the following XML.



  
    
      
    
  


On my typed list item object, I now have the one extra Column that I specified in my parameters file. LINQ will create a property for this field that is just an object. However, if you access this property, you can cast it to a TaxonomyFieldValueCollection or TaxonomyFieldValue, as appropriate. This provides exactly the information we wanted:

using (SPMySiteDataContext context = new SPMySiteDataContext("http://mysite"))
{
 var examples = from d in context.examples
      select d;

 foreach (var example in examples)
 {
  if (example.Specialty is TaxonomyFieldValueCollection)
  {
   foreach (TaxonomyFieldValue tfv in (TaxonomyFieldValueCollection)example.Specialty)
   {
    Console.WriteLine(tfv.Label);
   }
  }
  else if (example.Specialty is TaxonomyFieldValue)
  {
   TaxonomyFieldValue tfv = (TaxonomyFieldValue)example.Specialty;
   Console.WriteLine(tfv.Label);
  }
 }
}

2 comments:

  1. My list does not have a content type I typically run this param file:






    What would I do here to add the column I need?
    Thanks

    ReplyDelete
  2. what is name ="" class="" referring to in your xml?

    ReplyDelete