protected virtual Expression VisitOrganizationIndex(SqlOrganizationIndexExpression expression)
        {
            var columns         = VisitExpressionList(expression.Columns);
            var includedColumns = VisitExpressionList(expression.IncludedColumns);

            if (columns != expression.Columns || includedColumns != expression.IncludedColumns)
            {
                return(expression.ChangeColumns(columns, includedColumns));
            }

            return(expression);
        }
        private Expression BuildCreateTableExpression(TypeDescriptor typeDescriptor)
        {
            var columnExpressions = new List <SqlColumnDefinitionExpression>();

            this.currentTableConstraints = new List <SqlConstraintExpression>();

            var columnInfos = QueryBinder.GetColumnInfos
                              (
                this.model.TypeDescriptorProvider,
                typeDescriptor.PersistedProperties,
                (c, d) => c.IsPrimaryKey && !c.PropertyType.IsDataAccessObjectType(),
                (c, d) => c.IsPrimaryKey
                              );

            foreach (var columnInfo in columnInfos)
            {
                columnExpressions.Add(this.BuildColumnDefinition(columnInfo));
            }

            columnInfos = QueryBinder.GetColumnInfos
                          (
                this.model.TypeDescriptorProvider,
                typeDescriptor.PersistedPropertiesWithoutBackreferences.Where(c => !c.PropertyType.IsDataAccessObjectType()),
                (c, d) => d == 0 ? !c.IsPrimaryKey : c.IsPrimaryKey,
                (c, d) => d == 0 ? !c.IsPrimaryKey : c.IsPrimaryKey
                          );

            foreach (var columnInfo in columnInfos)
            {
                columnExpressions.Add(this.BuildColumnDefinition(columnInfo));
            }

            foreach (var property in typeDescriptor.PersistedPropertiesWithoutBackreferences
                     .Where(c => c.PropertyType.IsDataAccessObjectType()))
            {
                columnInfos = QueryBinder.GetColumnInfos
                              (
                    this.model.TypeDescriptorProvider,
                    new [] { property },
                    (c, d) => d == 0 || c.IsPrimaryKey,
                    (c, d) => c.IsPrimaryKey
                              );

                columnExpressions.AddRange(this.BuildForeignKeyColumnDefinitions(property, columnInfos));
            }

            columnExpressions.AddRange(this.BuildRelatedColumnDefinitions(typeDescriptor));

            var tableName = typeDescriptor.PersistedName;

            var primaryKeys = QueryBinder.GetPrimaryKeyColumnInfos(this.model.TypeDescriptorProvider, typeDescriptor);

            if (primaryKeys.Length > 0)
            {
                var columnNames = primaryKeys.Select(c => c.ColumnName);
                var compositePrimaryKeyConstraint = new SqlConstraintExpression(ConstraintType.PrimaryKey, this.formatterManager.GetPrimaryKeyConstraintName(typeDescriptor, typeDescriptor.PrimaryKeyProperties.ToArray()), columnNames.ToReadOnlyCollection());

                this.currentTableConstraints.Add(compositePrimaryKeyConstraint);
            }

            SqlOrganizationIndexExpression organizationIndex = null;

            var organizationAttributes = typeDescriptor
                                         .PersistedProperties
                                         .Where(c => c.OrganizationIndexAttribute != null)
                                         .Where(c => c.OrganizationIndexAttribute.IncludeOnly == false)
                                         .Select(c => new Tuple <OrganizationIndexAttribute, PropertyDescriptor>(c.OrganizationIndexAttribute, c))
                                         .OrderBy(c => c.Item1.CompositeOrder)
                                         .ToArray();

            if (organizationAttributes.Length > 0)
            {
                var organizationIndexName = this.formatterManager.GetIndexConstraintName(organizationAttributes.Select(c => c.Item2));

                organizationIndex = this.BuildOrganizationIndexExpression(organizationIndexName, organizationAttributes);
            }

            return(new SqlCreateTableExpression(new SqlTableExpression(tableName), false, columnExpressions, this.currentTableConstraints, organizationIndex));
        }