Programmatically create a site lookup column in SharePoint

We have automated almost everything about creating a "blank" publishing web site with landing pages, navigation parameters, even content pages.  One thing we found out with Features or even code is that you cannot create a list with its GUID; it will be provided to you after creation.  Obviously, if you have a Feature with a List and a site lookup column pointing to that list through its GUID, the feature will not work.

 

So we had to break our list & lookup columns from our features and create them programmatically after the feature is installed (or it could be part of the Activated event if you want).  In our case, we created an STSADM extension that creates a SharePoint Custom List, add its columns, add its data rows, create site lookup columns, and add them to the specified content type.  The input's obviously an Xml file.

 

Down to the point, creating a Lookup Column isn't terribly different than creating a standard column where you have to add it to the site columns collection.  However, instead of using the Add method, there's also an AddLookup method.  Basically, you need an SPWeb instance and an SPList instance pointing to your list and you can add the column with this :

 

                web.Fields.AddLookup(myNewColumnDisplayName, list.ID, list.ParentWeb.ID, myNewColumnIsRequired);

                SPFieldLookup lookup = (SPFieldLookup)web.Fields[myNewColumnDisplayName];

                lookup.AllowMultipleValues = myNewColumnAllowMultipleValues;

                lookup.Group = myNewColumnGroup;

                lookup.LookupField = myNewColumnLookupField;

                lookup.Update(true);

 

I've put in bold the parameters you have to include but that's about it, you now have a site lookup column created. Beware, you can create the column with the same display name multiple times so you will want to verify first if the column already exists. After that, you will want to add it to content types.

 

                newField = (SPField)lookup;

                SPContentType ct = web.ContentTypes[contentTypeName];

                bool fieldLinked = false;

                foreach (SPFieldLink fieldLink in ct.FieldLinks)

                {

                    if (fieldLink.DisplayName.Equals(columnLookup.DisplayName))

                    {

                        fieldLinked = true;

                        break;

                    }

                }

 

                if (!fieldLinked) {

                    ct.FieldLinks.Add(new SPFieldLink(newField));

                    ct.Update(true);

                }

 

Again, you have to validate that the link isn't already there (if you plan on being able to re-run your code as I can with an STSADM. You are now all set with your lookup columns!

 

Maxime