private void CreateConceptualComplexType(IEntity entity, string complexTypeName = "")
        {
            complexTypeName = !String.IsNullOrEmpty(complexTypeName)
                                  ? complexTypeName
                                  : entity is CommandEntity
                                        ? ResolveEntityMappedName(entity.EntityKey() + "complex", entity.Name)
                                        : ResolveEntityMappedName(entity.EntityKey(), entity.Name);

            //<ComplexType Name="GetCategoryById_Result">
            //  <Property Type="String" Name="CategoryId" Nullable="false" MaxLength="10" />
            //  <Property Type="String" Name="Name" Nullable="true" MaxLength="80" />
            //  <Property Type="String" Name="Descn" Nullable="true" MaxLength="255" />
            //</ComplexType>
            // Check to see if this has already been processed.
            if (_conceptualComplexTypes.Contains(entity.Name)) return;

            var type = ConceptualSchema.ComplexTypes.Where(c => c.Name.Equals(complexTypeName)).FirstOrDefault();
            if (type == null)
            {
                type = new ComplexType() { Name = complexTypeName };
                ConceptualSchema.ComplexTypes.Add(type);
            }

            type.Name = complexTypeName;
            type.SetAttributeValue(EdmxConstants.IsFunctionEntityCustomAttribute, entity is CommandEntity ? Boolean.TrueString : null);

            RemoveDuplicateConceptualComplexTypeProperties(entity, type, null);
            CreateConceptualComplexProperties(entity, type);

            _conceptualComplexTypes.Add(entity.Name);
        }
        private void RemoveDuplicateConceptualComplexTypeProperties(IEntity entity, ComplexType type, EntityType entityType)
        {
            var processed = new List<string>();
            var propertiesToRemove = new List<ComplexTypeProperty>();
            foreach (var property in type.Properties)
            {
                if (processed.Contains(property.Name))
                    propertiesToRemove.Add(property);
                else
                    processed.Add(property.Name);
            }

            // Remove extra properties contained in the ComplexType that are not in the Entity.
            propertiesToRemove.AddRange(from property in type.Properties
                                        where
                                            !(from prop in entity.Properties select prop.KeyName).Contains(property.Name) &&
                                            _removedStorageEntityProperties.Contains(String.Format(PROPERTY_KEY, entity.EntityKeyName, property.Name).ToLower()) && // And it has been removed from the storage model.
                                            !propertiesToRemove.Contains(property)
                                        select property);

            if (entityType != null)
            {
                // Remove extra properties contained in the ComplexType that are not in the Entity.
                propertiesToRemove.AddRange(from property in type.Properties
                                            where !(from prop in entityType.Properties select entityType.Name).Contains(property.Name) && !propertiesToRemove.Contains(property)
                                            select property);
            }

            foreach (var e in propertiesToRemove)
            {
                type.Properties.Remove(e);
            }

            type.Properties = (from p in type.Properties select p).ToList();
        }
        private void CreateConceptualComplexProperties(IEntity entity, ComplexType type)
        {
            //<Property Type="String" Name="Descn" Nullable="true" MaxLength="255" />
            foreach (ISchemaProperty property in entity.Properties)
            {
                var propertyName = ResolveEntityPropertyMappedName(entity.Name, property.KeyName, property.Name);
                var entityProperty = type.Properties.Where(p => propertyName.Equals(p.Name, StringComparison.OrdinalIgnoreCase) || property.KeyName.Equals(p.Name, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
                if (entityProperty == null)
                {
                    if (ExcludeProperty(property) && !_newStorageEntityProperties.Contains(String.Format("{0}-{1}", entity.Name, property.Name)))
                        continue;

                    entityProperty = new ComplexTypeProperty() { Name = ResolveEntityPropertyMappedName(entity.Name, property.KeyName, property.Name) };
                    type.Properties.Add(entityProperty);
                }
                else if (ExcludeProperty(property))
                {
                    type.Properties.Remove(entityProperty);
                    continue;
                }

                entityProperty.Name = propertyName;

                //Note: If the SystemType is prefixed with System than it will throw an error saying it cannot be resolved.
                entityProperty.Type = GetSystemType(property);

                if (!property.IsNullable)
                    entityProperty.Nullable = property.IsNullable;

                entityProperty.MaxLength = !String.IsNullOrEmpty(GetMaxLength(property)) ? GetMaxLength(property) : null;
            }
        }