protected virtual FieldLookup GetPrimaryField(DependentLookupFieldDefinition definition)
        {
            var fields = FieldLookupService.GetFieldCollection(this.ModelHost);

            return FieldLookupService.GetFieldAs<FieldLookup>(
                fields, definition.PrimaryLookupFieldId, definition.PrimaryLookupFieldInternalName, definition.PrimaryLookupFieldTitle);
        }
        protected virtual SPFieldLookup GetPrimaryField(object modelHost, DependentLookupFieldDefinition definition)
        {
            if (modelHost is SiteModelHost)
                return GetPrimaryLookupField((modelHost as SiteModelHost).HostSite.RootWeb.Fields, definition);
            else if (modelHost is WebModelHost)
                return GetPrimaryLookupField((modelHost as WebModelHost).HostWeb.Fields, definition);
            else if (modelHost is ListModelHost)
                return GetPrimaryLookupField((modelHost as ListModelHost).HostList.Fields, definition);

            throw new SPMeta2Exception("Unsupported model host");
        }
        private void DeployDependentLookupField(object modelHost, SPFieldCollection fields, DependentLookupFieldDefinition definition)
        {
            var primaryLookupField = GetPrimaryLookupField(fields, definition);
            var dependentLookupField = GetDependentLookupField(fields, definition);

            if (dependentLookupField == null)
            {
                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model = null,
                    EventType = ModelEventType.OnProvisioning,
                    Object = null,
                    ObjectType = typeof(SPFieldLookup),
                    ObjectDefinition = definition,
                    ModelHost = modelHost
                });

                var internalName = fields.AddDependentLookup(definition.InternalName, primaryLookupField.Id);

                //dependentLookupField = (SPFieldLookup)fields.CreateNewField(SPFieldType.Lookup.ToString(), definition.InternalName);

                dependentLookupField = GetDependentLookupField(fields, definition);
                dependentLookupField.Title = definition.Title;

                dependentLookupField.LookupList = primaryLookupField.LookupList;
                dependentLookupField.LookupWebId = primaryLookupField.LookupWebId;

                if (!string.IsNullOrEmpty(primaryLookupField.LookupList) &&
                string.IsNullOrEmpty(dependentLookupField.LookupList))
                {
                    dependentLookupField.LookupList = primaryLookupField.LookupList;
                }

                if (string.IsNullOrEmpty(dependentLookupField.PrimaryFieldId))
                    dependentLookupField.PrimaryFieldId = primaryLookupField.Id.ToString();

                dependentLookupField.ReadOnlyField = true;
                dependentLookupField.AllowMultipleValues = primaryLookupField.AllowMultipleValues;
                dependentLookupField.UnlimitedLengthInDocumentLibrary = primaryLookupField.UnlimitedLengthInDocumentLibrary;
                dependentLookupField.Direction = primaryLookupField.Direction;

                //dependentLookupField.Update(true);
                //dependentLookupField = GetDependentLookupField(fields, definition);
            }
            else
            {
                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model = null,
                    EventType = ModelEventType.OnProvisioning,
                    Object = dependentLookupField,
                    ObjectType = typeof(SPFieldLookup),
                    ObjectDefinition = definition,
                    ModelHost = modelHost
                });

            }

            dependentLookupField.Title = definition.Title;

            dependentLookupField.LookupField = definition.LookupField;

            if (!string.IsNullOrEmpty(primaryLookupField.LookupList) &&
                string.IsNullOrEmpty(dependentLookupField.LookupList))
            {
                dependentLookupField.LookupList = primaryLookupField.LookupList;
            }
            dependentLookupField.LookupWebId = primaryLookupField.LookupWebId;

            dependentLookupField.Group = definition.Group ?? string.Empty;
            dependentLookupField.Description = definition.Description ?? string.Empty;

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model = null,
                EventType = ModelEventType.OnProvisioned,
                Object = dependentLookupField,
                ObjectType = typeof(SPFieldLookup),
                ObjectDefinition = definition,
                ModelHost = modelHost
            });

            if (fields.List != null)
                dependentLookupField.Update();
            else
                dependentLookupField.Update(true);
        }
 private void DeploySiteDependentLookup(object modelHost, SiteModelHost siteModelHost, DependentLookupFieldDefinition definition)
 {
     DeployDependentLookupField(modelHost, siteModelHost.HostSite.RootWeb.Fields, definition);
 }
 private void DeployWebDependentLookup(object modelHost, WebModelHost webModelHost, DependentLookupFieldDefinition definition)
 {
     DeployDependentLookupField(modelHost, webModelHost.HostWeb.Fields, definition);
 }
 private void DeployListDependentLookup(object modelHost, ListModelHost listModelHost, DependentLookupFieldDefinition definition)
 {
     DeployDependentLookupField(modelHost, listModelHost.HostList.Fields, definition);
 }
        protected virtual SPFieldLookup GetPrimaryLookupField(SPFieldCollection fields, DependentLookupFieldDefinition definition)
        {
            if (definition.PrimaryLookupFieldId.HasGuidValue())
                return fields[definition.PrimaryLookupFieldId.Value] as SPFieldLookup;

            if (!string.IsNullOrEmpty(definition.PrimaryLookupFieldInternalName))
                return fields.GetFieldByInternalName(definition.PrimaryLookupFieldInternalName) as SPFieldLookup; ;

            if (!string.IsNullOrEmpty(definition.PrimaryLookupFieldTitle))
                return fields.GetField(definition.PrimaryLookupFieldTitle) as SPFieldLookup; ;

            throw new SPMeta2Exception("PrimaryLookupFieldTitle / PrimaryLookupFieldInternalName / PrimaryLookupFieldId need to be defined");
        }
        protected virtual SPFieldLookup GetDependentLookupField(SPFieldCollection fields, DependentLookupFieldDefinition definition)
        {
            var targetName = definition.InternalName.ToUpper();

            return fields
                     .OfType<SPField>()
                     .FirstOrDefault(f => f.InternalName.ToUpper() == targetName) as SPFieldLookup;
        }
        private void DeployDependentLookupField(object modelHost, FieldCollection fields, DependentLookupFieldDefinition definition)
        {
            var context = fields.Context;

            var primaryLookupField = GetPrimaryLookupField(fields, definition);
            var dependentLookupField = GetDependentLookupField(fields, definition);

            if (dependentLookupField == null)
            {
                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model = null,
                    EventType = ModelEventType.OnProvisioning,
                    Object = null,
                    ObjectType = typeof(FieldLookup),
                    ObjectDefinition = definition,
                    ModelHost = modelHost
                });

                var internalName = fields.AddDependentLookup(definition.InternalName, primaryLookupField, definition.LookupField);

                dependentLookupField = GetDependentLookupField(fields, definition);
                dependentLookupField.Title = definition.Title;

                dependentLookupField.LookupList = primaryLookupField.LookupList;
                dependentLookupField.LookupWebId = primaryLookupField.LookupWebId;

                if (!string.IsNullOrEmpty(primaryLookupField.LookupList) &&
                string.IsNullOrEmpty(dependentLookupField.LookupList))
                {
                    dependentLookupField.LookupList = primaryLookupField.LookupList;
                }

                if (string.IsNullOrEmpty(dependentLookupField.PrimaryFieldId))
                    dependentLookupField.PrimaryFieldId = primaryLookupField.Id.ToString();

                dependentLookupField.ReadOnlyField = true;
                dependentLookupField.AllowMultipleValues = primaryLookupField.AllowMultipleValues;

                // unsuppoeted in CSOM yet
                //dependentLookupField.UnlimitedLengthInDocumentLibrary = primaryLookupField.UnlimitedLengthInDocumentLibrary;
                dependentLookupField.Direction = primaryLookupField.Direction;
            }
            else
            {
                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model = null,
                    EventType = ModelEventType.OnProvisioning,
                    Object = dependentLookupField,
                    ObjectType = typeof(FieldLookup),
                    ObjectDefinition = definition,
                    ModelHost = modelHost
                });

            }

            dependentLookupField.Title = definition.Title;

            dependentLookupField.LookupField = definition.LookupField;

            if (!string.IsNullOrEmpty(primaryLookupField.LookupList) &&
                string.IsNullOrEmpty(dependentLookupField.LookupList))
            {
                dependentLookupField.LookupList = primaryLookupField.LookupList;
            }
            dependentLookupField.LookupWebId = primaryLookupField.LookupWebId;

            dependentLookupField.Group = string.IsNullOrEmpty(definition.Group) ? "Custom" : definition.Group; 
            dependentLookupField.Description = definition.Description ?? string.Empty;

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model = null,
                EventType = ModelEventType.OnProvisioned,
                Object = dependentLookupField,
                ObjectType = typeof(FieldLookup),
                ObjectDefinition = definition,
                ModelHost = modelHost
            });

            dependentLookupField.UpdateAndPushChanges(true);

            context.ExecuteQuery();
        }
        protected virtual FieldLookup GetPrimaryLookupField(FieldCollection fields, DependentLookupFieldDefinition definition)
        {
            var context = fields.Context;

            Field result = null;

            if (definition.PrimaryLookupFieldId.HasGuidValue())
                result = fields.GetById(definition.PrimaryLookupFieldId.Value);

            if (!string.IsNullOrEmpty(definition.PrimaryLookupFieldInternalName))
                result = fields.GetByInternalNameOrTitle(definition.PrimaryLookupFieldInternalName);

            if (!string.IsNullOrEmpty(definition.PrimaryLookupFieldTitle))
                result = fields.GetByTitle(definition.PrimaryLookupFieldTitle);

            context.Load(result);
            context.ExecuteQuery();

            return context.CastTo<FieldLookup>(result);
        }
        protected virtual FieldLookup GetDependentLookupField(FieldCollection fields, 
            DependentLookupFieldDefinition definition)
        {
            var context = fields.Context;

            Field field = null;

            var scope = new ExceptionHandlingScope(context);

            using (scope.StartScope())
            {
                using (scope.StartTry())
                {
                    fields.GetByInternalNameOrTitle(definition.InternalName);
                }

                using (scope.StartCatch())
                {

                }
            }

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "ExecuteQuery()");
            context.ExecuteQueryWithTrace();

            if (!scope.HasException)
            {
                field = fields.GetByInternalNameOrTitle(definition.InternalName);
                context.Load(field);

                context.ExecuteQueryWithTrace();

                return context.CastTo<FieldLookup>(field);
            }

            return null;
        }