public static void SetControlProperties(this ListMetadataField metaField, DbField dbField)
        {
            XDocument xDoc = new XDocument(new XElement("Field",
                                                        new XAttribute("Type", dbField.TypeAsString)));
            XElement root = xDoc.Root;

            switch (dbField.Type)
            {
            case SPFieldType.Text:
                root.Add(new XAttribute("MaxLength", (dbField as DbFieldText).MaxLength));
                break;

            case SPFieldType.Note:
                root.Add(new XAttribute("NumLines", (dbField as DbFieldNote).NumberOfLines));
                break;

            case SPFieldType.Boolean:
                break;

            case SPFieldType.DateTime:
                root.Add(new XAttribute("Format", (dbField as DbFieldDateTime).Format));
                break;

            case SPFieldType.Number:
                DbFieldNumber numFld = dbField as DbFieldNumber;
                root.Add(new XAttribute("Decimals", numFld.DecimalPlaces));
                root.Add(new XAttribute("Min", numFld.MinValue));
                root.Add(new XAttribute("Max", numFld.MaxValue));
                break;

            case SPFieldType.Recurrence:
                dbField = new DbFieldRecurrence(metaField.Id);
                break;

            case SPFieldType.Choice:
                DbFieldChoice chFld = dbField as DbFieldChoice;
                root.Add(new XAttribute("Format", chFld.ControlType));     // "Dropdown" or "RadioButtons" or "Checkboxes"
                root.Add(new XElement("CHOICES", chFld.Choices.Select(x => new XElement("CHOICE", x))));
                break;

            case SPFieldType.Lookup:
                DbFieldLookup loFld = dbField as DbFieldLookup;
                root.Add(new XAttribute("Source", loFld.ListSource));
                root.Add(new XAttribute("List", loFld.ListId));
                root.Add(new XAttribute("LookupKey", loFld.LookupKey));
                root.Add(new XAttribute("LookupField", loFld.LookupField));
                if (!String.IsNullOrWhiteSpace(loFld.DependentParent))
                {
                    root.Add(new XAttribute("DependentParent", loFld.DependentParent));
                    root.Add(new XAttribute("DependentParentField", loFld.DependentParentField));
                    root.Add(new XAttribute("FilterByField", loFld.FilterByField));
                }
                break;

            case SPFieldType.User:
                DbFieldUser usFld = dbField as DbFieldUser;
                root.Add(new XAttribute("Source", usFld.ListSource));
                root.Add(new XAttribute("List", usFld.ListId));
                root.Add(new XAttribute("LookupKey", usFld.LookupKey));
                root.Add(new XAttribute("LookupField", usFld.LookupField));
                root.Add(new XAttribute("AllowSelection", usFld.AllowSelection));
                root.Add(new XAttribute("ChooseFrom", usFld.ChooseFrom));
                root.Add(new XAttribute("ChooseFromGroup", usFld.ChooseFromGroup));
                break;

            default:
                break;
            }

            metaField.ControlProperties = xDoc.ToString(SaveOptions.DisableFormatting);
        }
        public static DbField GetDbField(this ListMetadataField metaField)
        {
            DbField dbField = null;

            XDocument xDoc = XDocument.Parse(metaField.ControlProperties);
            XElement  root = xDoc.Root;

            XAttribute fieldTypeAttr = root.Attribute("Type");

            if (fieldTypeAttr != null)
            {
                SPFieldType pFldType = EnumHelper.GetEnumByDescription <SPFieldType>(fieldTypeAttr.Value);
                switch (pFldType)
                {
                case SPFieldType.Guid:
                    dbField = new DbFieldGuid(metaField.Id);
                    break;

                case SPFieldType.Text:
                    DbFieldText txtFld = new DbFieldText(metaField.Id);

                    int        mLen          = 0;
                    XAttribute maxLengthAttr = root.Attribute("MaxLength");
                    if (maxLengthAttr != null && Int32.TryParse(maxLengthAttr.Value, out mLen))
                    {
                        txtFld.MaxLength = mLen;
                    }

                    dbField = txtFld;
                    break;

                case SPFieldType.Note:
                    DbFieldNote noteFld = new DbFieldNote(metaField.Id);

                    int        nol     = 0;
                    XAttribute nolAttr = root.Attribute("NumLines");
                    if (nolAttr != null && Int32.TryParse(nolAttr.Value, out nol))
                    {
                        noteFld.NumberOfLines = nol;
                    }

                    dbField = noteFld;
                    break;

                case SPFieldType.Boolean:
                    dbField = new DbFieldBoolean(metaField.Id);
                    break;

                case SPFieldType.DateTime:
                    DbFieldDateTime dtFld = new DbFieldDateTime(metaField.Id);

                    XAttribute formatAttr = root.Attribute("Format");
                    if (formatAttr != null && !string.IsNullOrEmpty(formatAttr.Value))
                    {
                        dtFld.Format = formatAttr.Value;     // "DateOnly" or "DateTime"
                    }
                    dbField = dtFld;
                    break;

                case SPFieldType.Number:
                    DbFieldNumber numFld = new DbFieldNumber(metaField.Id);

                    int        dcp     = 0;
                    XAttribute decAttr = root.Attribute("Decimals");
                    if (decAttr != null && Int32.TryParse(decAttr.Value, out dcp))
                    {
                        numFld.DecimalPlaces = dcp;     // -1 = 'Automatic'
                    }
                    double     minV    = 0;
                    XAttribute minAttr = root.Attribute("Min");
                    if (minAttr != null && Double.TryParse(minAttr.Value.Replace(',', '.'), NumberStyles.Any, CultureInfo.InvariantCulture, out minV))
                    {
                        numFld.MinValue = minV;
                    }

                    double     maxV    = 0;
                    XAttribute maxAttr = root.Attribute("Max");
                    if (maxAttr != null && Double.TryParse(maxAttr.Value.Replace(',', '.'), NumberStyles.Any, CultureInfo.InvariantCulture, out maxV))
                    {
                        numFld.MaxValue = maxV;
                    }

                    dbField = numFld;
                    break;

                case SPFieldType.Recurrence:
                    dbField = new DbFieldRecurrence(metaField.Id);
                    break;

                case SPFieldType.Choice:
                    DbFieldChoice chFld = new DbFieldChoice(metaField.Id);

                    XAttribute chFormatAttr = root.Attribute("Format");
                    if (chFormatAttr != null && !string.IsNullOrEmpty(chFormatAttr.Value))
                    {
                        chFld.ControlType = chFormatAttr.Value;     // "Dropdown" or "RadioButtons" or "Checkboxes"
                    }
                    XElement choicesEl = root.Element("CHOICES");
                    if (choicesEl != null)
                    {
                        chFld.Choices = choicesEl.Elements("CHOICE").Select(x => x.Value).ToArray();
                    }

                    dbField = chFld;
                    break;

                case SPFieldType.Lookup:
                    var lookFld = new DbFieldLookup(metaField.Id);

                    var listSourceAttr = root.Attribute("Source");
                    if (listSourceAttr != null && !string.IsNullOrEmpty(listSourceAttr.Value))
                    {
                        lookFld.ListSource = listSourceAttr.Value.ToInt();
                    }

                    var listAttr = root.Attribute("List");
                    if (listAttr != null && !string.IsNullOrEmpty(listAttr.Value))
                    {
                        lookFld.ListId = listAttr.Value;
                    }

                    var listKeyAttr = root.Attribute("LookupKey");
                    if (listKeyAttr != null && !string.IsNullOrEmpty(listKeyAttr.Value))
                    {
                        lookFld.LookupKey = listKeyAttr.Value;
                    }

                    var lfAttr = root.Attribute("LookupField");
                    if (lfAttr != null && !string.IsNullOrEmpty(lfAttr.Value))
                    {
                        lookFld.LookupField = lfAttr.Value;
                    }

                    var dependentParentAttr = root.Attribute("DependentParent");
                    if (dependentParentAttr != null && !string.IsNullOrEmpty(dependentParentAttr.Value))
                    {
                        lookFld.DependentParent = dependentParentAttr.Value;
                    }

                    var dependentParentFieldAttr = root.Attribute("DependentParentField");
                    if (dependentParentFieldAttr != null && !string.IsNullOrEmpty(dependentParentFieldAttr.Value))
                    {
                        lookFld.DependentParentField = dependentParentFieldAttr.Value;
                    }

                    var filterByFieldAttr = root.Attribute("FilterByField");
                    if (filterByFieldAttr != null && !string.IsNullOrEmpty(filterByFieldAttr.Value))
                    {
                        lookFld.FilterByField = filterByFieldAttr.Value;
                    }

                    dbField = lookFld;
                    break;

                case SPFieldType.User:
                    var userFld = new DbFieldUser(metaField.Id);

                    var listSourceAttr2 = root.Attribute("Source");
                    if (listSourceAttr2 != null && !string.IsNullOrEmpty(listSourceAttr2.Value))
                    {
                        userFld.ListSource = listSourceAttr2.Value.ToInt();
                    }

                    var listAttr2 = root.Attribute("List");
                    if (listAttr2 != null && !string.IsNullOrEmpty(listAttr2.Value))
                    {
                        userFld.ListId = listAttr2.Value;
                    }

                    var listKeyAttr2 = root.Attribute("LookupKey");
                    if (listKeyAttr2 != null && !string.IsNullOrEmpty(listKeyAttr2.Value))
                    {
                        userFld.LookupKey = listKeyAttr2.Value;
                    }

                    var lfAttr2 = root.Attribute("LookupField");
                    if (lfAttr2 != null && !string.IsNullOrEmpty(lfAttr2.Value))
                    {
                        userFld.LookupField = lfAttr2.Value;
                    }

                    var asAttr2 = root.Attribute("AllowSelection");
                    if (asAttr2 != null && !string.IsNullOrEmpty(asAttr2.Value))
                    {
                        userFld.AllowSelection = asAttr2.Value;
                    }

                    var cfAttr2 = root.Attribute("ChooseFrom");
                    if (cfAttr2 != null && !string.IsNullOrEmpty(cfAttr2.Value))
                    {
                        userFld.ChooseFrom = cfAttr2.Value;
                    }

                    var cfgAttr2 = root.Attribute("ChooseFromGroup");
                    if (cfgAttr2 != null && !string.IsNullOrEmpty(cfgAttr2.Value))
                    {
                        userFld.ChooseFromGroup = cfgAttr2.Value;
                    }

                    dbField = userFld;
                    break;

                default:
                    break;
                }

                if (dbField != null)
                {
                    // common attributes
                    dbField.ReadOnly     = metaField.ReadOnly;
                    dbField.DisplayName  = metaField.FieldName;
                    dbField.InternalName = metaField.InternalName;
                    dbField.DefaultValue = metaField.DefaultValue;
                    dbField.Required     = metaField.Required;
                    dbField.Hidden       = metaField.Hidden;
                }
            }

            return(dbField);
        }