public override void GenerateCode(MigrationCodeGenerator generator, IndentedStringBuilder stringBuilder)
        {
            Check.NotNull(generator, "generator");
            Check.NotNull(stringBuilder, "stringBuilder");

            generator.Generate(this, stringBuilder);
        }
        public override void Generate(DropDefaultConstraintOperation dropDefaultConstraintOperation, IndentedStringBuilder stringBuilder)
        {
            Check.NotNull(dropDefaultConstraintOperation, "dropDefaultConstraintOperation");
            Check.NotNull(stringBuilder, "stringBuilder");

            var constraintNameVariable = "@var" + _variableCount++;

            stringBuilder
                .Append("DECLARE ")
                .Append(constraintNameVariable)
                .AppendLine(" nvarchar(128)");

            stringBuilder
                .Append("SELECT ")
                .Append(constraintNameVariable)
                .Append(" = name FROM sys.default_constraints WHERE parent_object_id = OBJECT_ID(N")
                .Append(DelimitLiteral(dropDefaultConstraintOperation.TableName))
                .Append(") AND COL_NAME(parent_object_id, parent_column_id) = N")
                .AppendLine(DelimitLiteral(dropDefaultConstraintOperation.ColumnName));

            stringBuilder
                .Append("EXECUTE('ALTER TABLE ")
                .Append(DelimitIdentifier(dropDefaultConstraintOperation.TableName))
                .Append(" DROP CONSTRAINT \"' + ")
                .Append(constraintNameVariable)
                .Append(" + '\"')");
        }
        public virtual ScaffoldedMigration ScaffoldMigration([NotNull] string migrationName)
        {
            Check.NotEmpty(migrationName, "migrationName");

            if (MigrationAssembly.Migrations.Any(m => m.GetMigrationName() == migrationName))
            {
                throw new InvalidOperationException(Strings.FormatDuplicateMigrationName(migrationName));
            }

            var migration = CreateMigration(migrationName);

            var migrationCode = new IndentedStringBuilder();
            var migrationMetadataCode = new IndentedStringBuilder();
            var snapshotModelCode = new IndentedStringBuilder();

            ScaffoldMigration(migration, migrationCode, migrationMetadataCode);
            ScaffoldSnapshotModel(migration.TargetModel, snapshotModelCode);

            return
                new ScaffoldedMigration()
                    {
                        MigrationNamespace = MigrationNamespace,
                        MigrationClass = GetClassName(migration),
                        SnapshotModelClass = GetClassName(migration.TargetModel),
                        MigrationCode = migrationCode.ToString(),
                        MigrationMetadataCode = migrationMetadataCode.ToString(),
                        SnapshotModelCode = snapshotModelCode.ToString()
                    };
        }
        public void Append_line_at_start_with_indent()
        {
            var indentedStringBuilder = new IndentedStringBuilder();

            using (indentedStringBuilder.Indent())
            {
                indentedStringBuilder.AppendLine("Foo");
            }

            Assert.Equal("    Foo\r\n", indentedStringBuilder.ToString());
        }
        public virtual IEnumerable<SqlStatement> Generate([NotNull] IEnumerable<MigrationOperation> migrationOperations)
        {
            Check.NotNull(migrationOperations, "migrationOperations");

            foreach (var operation in migrationOperations)
            {
                var builder = new IndentedStringBuilder();
                operation.GenerateSql(this, builder);
                yield return new SqlStatement(builder.ToString());
            }
        }
        public override void Generate(RenameTableOperation renameTableOperation, IndentedStringBuilder stringBuilder)
        {
            Check.NotNull(renameTableOperation, "renameTableOperation");

            stringBuilder
                .Append("EXECUTE sp_rename @objname = N")
                .Append(DelimitLiteral(renameTableOperation.TableName))
                .Append(", @newname = N")
                .Append(DelimitLiteral(renameTableOperation.NewTableName))
                .Append(", @objtype = N'OBJECT'");
        }
        public void Append_line_in_middle_when_no_new_line()
        {
            var indentedStringBuilder = new IndentedStringBuilder();

            indentedStringBuilder.AppendLine("Foo");

            using (indentedStringBuilder.Indent())
            {
                indentedStringBuilder.AppendLine("Foo");
            }

            Assert.Equal("Foo\r\n    Foo\r\n", indentedStringBuilder.ToString());
        }
        public void Generate_empty_model()
        {
            var builder = new ModelBuilder();

            var stringBuilder = new IndentedStringBuilder();
            new CSharpModelCodeGenerator().Generate(builder.Model, stringBuilder);

            Assert.Equal(
                @"var builder = new ModelBuilder();

return builder.Model;",
                stringBuilder.ToString());
        }
        public override void Generate(RenameColumnOperation renameColumnOperation, IndentedStringBuilder stringBuilder)
        {
            Check.NotNull(renameColumnOperation, "renameColumnOperation");

            stringBuilder
                .Append("EXECUTE sp_rename @objname = N'")
                .Append(EscapeLiteral(renameColumnOperation.TableName))
                .Append(".")
                .Append(EscapeLiteral(renameColumnOperation.ColumnName))
                .Append("', @newname = N")
                .Append(DelimitLiteral(renameColumnOperation.NewColumnName))
                .Append(", @objtype = N'COLUMN'");
        }
        public override string Generate(
            string migrationNamespace,
            string migrationName,
            IReadOnlyList<MigrationOperation> upOperations,
            IReadOnlyList<MigrationOperation> downOperations)
        {
            Check.NotEmpty(migrationNamespace, nameof(migrationNamespace));
            Check.NotEmpty(migrationName, nameof(migrationName));
            Check.NotNull(upOperations, nameof(upOperations));
            Check.NotNull(downOperations, nameof(downOperations));

            var builder = new IndentedStringBuilder();
            builder
                .AppendLine("using System.Collections.Generic;")
                .AppendLine("using Microsoft.Data.Entity.Relational.Migrations;")
                .AppendLine("using Microsoft.Data.Entity.Relational.Migrations.Builders;")
                .AppendLine("using Microsoft.Data.Entity.Relational.Migrations.Operations;")
                .AppendLine()
                .Append("namespace ").AppendLine(migrationNamespace)
                .AppendLine("{");
            using (builder.Indent())
            {
                builder
                    .Append("public partial class ").Append(_code.Identifier(migrationName)).AppendLine(" : Migration")
                    .AppendLine("{");
                using (builder.Indent())
                {
                    builder
                        .AppendLine("public override void Up(MigrationBuilder migration)")
                        .AppendLine("{");
                    using (builder.Indent())
                    {
                        _operationGenerator.Generate("migration", upOperations, builder);
                    }
                    builder
                        .AppendLine("}")
                        .AppendLine()
                        .AppendLine("public override void Down(MigrationBuilder migration)")
                        .AppendLine("{");
                    using (builder.Indent())
                    {
                        _operationGenerator.Generate("migration", downOperations, builder);
                    }
                    builder.AppendLine("}");
                }
                builder.AppendLine("}");
            }
            builder.AppendLine("}");

            return builder.ToString();
        }
        public virtual SqlBatchBuilder EndBatch()
        {
            var sql = _stringBuilder.ToString();
            var sqlBatch = new SqlBatch(sql);
            sqlBatch.SuppressTransaction = _transactionSuppressed;

            if (!string.IsNullOrEmpty(sql))
            {
                _batches.Add(sqlBatch);
            }

            _stringBuilder = new IndentedStringBuilder();

            return this;
        }
        public void Generate_empty_model_with_annotations()
        {
            var builder = new ModelBuilder()
                .Annotation("A1", "V1")
                .Annotation("A2", "V2");

            var stringBuilder = new IndentedStringBuilder();
            new CSharpModelCodeGenerator().Generate(builder.Model, stringBuilder);

            Assert.Equal(
                @"var builder = new ModelBuilder()
    .Annotation(""A1"", ""V1"")
    .Annotation(""A2"", ""V2"");

return builder.Model;",
                stringBuilder.ToString());
        }
        public override void Generate(IModel model, IndentedStringBuilder stringBuilder)
        {
            stringBuilder.Append("var builder = new ModelBuilder()");

            using (stringBuilder.Indent())
            {
                GenerateAnnotations(model.Annotations.ToArray(), stringBuilder);
            }

            stringBuilder.AppendLine(";");

            GenerateEntityTypes(model.EntityTypes, stringBuilder);

            stringBuilder
                .AppendLine()
                .Append("return builder.Model;");
        }
        protected virtual void GenerateEntityTypes(
            IReadOnlyList<IEntityType> entityTypes, IndentedStringBuilder stringBuilder)
        {
            Check.NotNull(entityTypes, nameof(entityTypes));
            Check.NotNull(stringBuilder, nameof(stringBuilder));

            foreach (var entityType in entityTypes)
            {
                stringBuilder.AppendLine();

                GenerateEntityType(entityType, stringBuilder, GenerateEntityTypeOptions.Primary);
            }

            foreach (var entityType in entityTypes.Where(e => e.GetForeignKeys().Any()))
            {
                stringBuilder.AppendLine();

                GenerateEntityType(entityType, stringBuilder, GenerateEntityTypeOptions.Secondary);
            }
        }
        protected override void GenerateTableConstraints(
            CreateTableOperation createTableOperation,
            IndentedStringBuilder stringBuilder)
        {
            Check.NotNull(createTableOperation, "createTableOperation");
            Check.NotNull(stringBuilder, "stringBuilder");

            foreach (var foreignKey in createTableOperation.Table.ForeignKeys)
            {
                stringBuilder.AppendLine(",");
                GenerateForeignKey(
                    new AddForeignKeyOperation(
                        foreignKey.Table.Name,
                        foreignKey.Name,
                        foreignKey.Columns.Select(c => c.Name).ToArray(),
                        foreignKey.ReferencedTable.Name,
                        foreignKey.ReferencedColumns.Select(c => c.Name).ToArray(),
                        foreignKey.CascadeDelete),
                    stringBuilder);
            }
        }
        public override void Generate(AddDefaultConstraintOperation addDefaultConstraintOperation, IndentedStringBuilder stringBuilder)
        {
            Check.NotNull(addDefaultConstraintOperation, "addDefaultConstraintOperation");
            Check.NotNull(stringBuilder, "stringBuilder");

            var tableName = addDefaultConstraintOperation.TableName;
            var columnName = addDefaultConstraintOperation.ColumnName;

            stringBuilder
                .Append("ALTER TABLE ")
                .Append(DelimitIdentifier(tableName))
                .Append(" ADD CONSTRAINT ")
                .Append(DelimitIdentifier("DF_" + tableName + "_" + columnName))
                .Append(" DEFAULT ");

            stringBuilder.Append(addDefaultConstraintOperation.DefaultSql ?? GenerateLiteral(addDefaultConstraintOperation.DefaultValue));

            stringBuilder
                .Append(" FOR ")
                .Append(DelimitIdentifier(columnName));
        }
        public void Generate_entity_type_with_shadow_property()
        {
            var builder = new ModelBuilder();
            builder.Entity<Customer>(b =>
                {
                    b.Property<int>("Id", shadowProperty: true);
                    b.Key(e => e.Id);
                });

            var stringBuilder = new IndentedStringBuilder();
            new CSharpModelCodeGenerator().Generate(builder.Model, stringBuilder);

            Assert.Equal(
                @"var builder = new ModelBuilder();

builder.Entity(""Customer"", b =>
    {
        b.Property<int>(""Id"", shadowProperty: true);
        b.Key(""Id"");
    });

return builder.Model;",
                stringBuilder.ToString());
        }
        public void Generate_entity_type_with_composite_key()
        {
            var builder = new ModelBuilder();
            builder.Entity<Customer>(b =>
                {
                    b.Property(e => e.Id);
                    b.Property(e => e.Name);
                    b.Key(e => new { e.Id, e.Name })
                        .Annotation("A1", "V1")
                        .Annotation("A2", "V2");
                });

            var stringBuilder = new IndentedStringBuilder();
            new CSharpModelCodeGenerator().Generate(builder.Model, stringBuilder);

            Assert.Equal(
                @"var builder = new ModelBuilder();

builder.Entity(""Customer"", b =>
    {
        b.Property<int>(""Id"");
        b.Property<string>(""Name"");
        b.Key(k => k.Properties(""Id"", ""Name"")
            .Annotation(""A1"", ""V1"")
            .Annotation(""A2"", ""V2""));
    });

return builder.Model;",
                stringBuilder.ToString());
        }
 public override void GenerateSql(
     MigrationOperationSqlGenerator generator,
     IndentedStringBuilder stringBuilder)
 {
 }
        public override string GenerateMetadata(
            string migrationNamespace,
            Type contextType,
            string migrationName,
            string migrationId,
            string productVersion,
            IModel targetModel)
        {
            Check.NotEmpty(migrationNamespace, nameof(migrationNamespace));
            Check.NotNull(contextType, nameof(contextType));
            Check.NotEmpty(migrationName, nameof(migrationName));
            Check.NotEmpty(migrationId, nameof(migrationId));
            Check.NotEmpty(productVersion, nameof(productVersion));
            Check.NotNull(targetModel, nameof(targetModel));

            var builder = new IndentedStringBuilder();
            builder
                .AppendLine("using System;")
                .AppendLine("using Microsoft.Data.Entity;")
                .AppendLine("using Microsoft.Data.Entity.Metadata;")
                .AppendLine("using Microsoft.Data.Entity.Relational.Migrations.Infrastructure;")
                .Append("using ").Append(contextType.Namespace).AppendLine(";")
                .AppendLine()
                .Append("namespace ").AppendLine(migrationNamespace)
                .AppendLine("{");
            using (builder.Indent())
            {
                builder
                    .Append("[ContextType(typeof(").Append(_code.Reference(contextType)).AppendLine("))]")
                    .Append("partial class ").AppendLine(_code.Identifier(migrationName))
                    .AppendLine("{");
                using (builder.Indent())
                {
                    builder
                        .AppendLine("public override string Id")
                        .AppendLine("{");
                    using (builder.Indent())
                    {
                        builder.Append("get { return ").Append(_code.Literal(migrationId)).AppendLine("; }");
                    }
                    builder
                        .AppendLine("}")
                        .AppendLine()
                        .AppendLine("public override string ProductVersion")
                        .AppendLine("{");
                    using (builder.Indent())
                    {
                        builder.Append("get { return ").Append(_code.Literal(productVersion)).AppendLine("; }");
                    }
                    builder
                        .AppendLine("}")
                        .AppendLine()
                        .AppendLine("public override void BuildTargetModel(ModelBuilder builder)")
                        .AppendLine("{");
                    using (builder.Indent())
                    {
                        // TODO: Optimize. This is repeated below
                        _modelGenerator.Generate(targetModel, builder);
                    }
                    builder.AppendLine("}");
                }
                builder.AppendLine("}");
            }
            builder.AppendLine("}");

            return builder.ToString();
        }
        public virtual string ScriptMigrations(
            string fromMigrationName,
            string toMigrationName,
            bool idempotent = false)
        {
            var migrations = _migrationAssembly.Migrations;

            if (string.IsNullOrEmpty(fromMigrationName))
            {
                fromMigrationName = InitialDatabase;
            }
            else if (fromMigrationName != InitialDatabase)
            {
                fromMigrationName = _idGenerator.ResolveId(fromMigrationName, migrations);
            }

            if (string.IsNullOrEmpty(toMigrationName))
            {
                toMigrationName = migrations.Last().Id;
            }
            else if (toMigrationName != InitialDatabase)
            {
                toMigrationName = _idGenerator.ResolveId(toMigrationName, migrations);
            }

            var builder = new IndentedStringBuilder();

            // If going up...
            if (string.Compare(fromMigrationName, toMigrationName, StringComparison.OrdinalIgnoreCase) <= 0)
            {
                var migrationsToApply = migrations.Where(
                    m => string.Compare(m.Id, fromMigrationName, StringComparison.OrdinalIgnoreCase) > 0
                         && string.Compare(m.Id, toMigrationName, StringComparison.OrdinalIgnoreCase) <= 0);
                var checkFirst = true;
                foreach (var migration in migrationsToApply)
                {
                    if (checkFirst)
                    {
                        if (migration == migrations[0])
                        {
                            builder.AppendLine(_historyRepository.Create(ifNotExists: true));
                            builder.AppendLine(_sqlGenerator.BatchSeparator);
                            builder.AppendLine();
                        }

                        checkFirst = false;
                    }

                    _logger.Value.LogVerbose(Strings.GeneratingUp(migration.Id));

                    foreach (var batch in ApplyMigration(migration))
                    {
                        if (idempotent)
                        {
                            builder.AppendLine(_historyRepository.BeginIfNotExists(migration.Id));
                            using (builder.Indent())
                            {
                                var lines = batch.Sql.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
                                foreach (var line in lines)
                                {
                                    builder.AppendLine(line);
                                }
                            }
                            builder.AppendLine(_historyRepository.EndIf());
                        }
                        else
                        {
                            builder.Append(batch.Sql);
                        }

                        builder.AppendLine(_sqlGenerator.BatchSeparator);
                        builder.AppendLine();
                    }
                }
            }
            else // If going down...
            {
                var migrationsToRevert = migrations
                    .Where(
                        m => string.Compare(m.Id, toMigrationName, StringComparison.OrdinalIgnoreCase) > 0
                             && string.Compare(m.Id, fromMigrationName, StringComparison.OrdinalIgnoreCase) <= 0)
                    .OrderByDescending(m => m.Id);
                foreach (var migration in migrationsToRevert)
                {
                    _logger.Value.LogVerbose(Strings.GeneratingDown(migration.Id));

                    foreach (var batch in RevertMigration(migration))
                    {
                        if (idempotent)
                        {
                            builder.AppendLine(_historyRepository.BeginIfExists(migration.Id));
                            using (builder.Indent())
                            {
                                var lines = batch.Sql.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
                                foreach (var line in lines)
                                {
                                    builder.AppendLine(line);
                                }
                            }
                            builder.AppendLine(_historyRepository.EndIf());
                        }
                        else
                        {
                            builder.Append(batch.Sql);
                        }

                        builder.AppendLine(_sqlGenerator.BatchSeparator);
                        builder.AppendLine();
                    }
                }
            }

            return builder.ToString();
        }
        public override string GenerateSnapshot(
            string modelSnapshotNamespace,
            Type contextType,
            string modelSnapshotName,
            IModel model)
        {
            Check.NotEmpty(modelSnapshotNamespace, nameof(modelSnapshotNamespace));
            Check.NotNull(contextType, nameof(contextType));
            Check.NotEmpty(modelSnapshotName, nameof(modelSnapshotName));
            Check.NotNull(model, nameof(model));

            var builder = new IndentedStringBuilder();
            builder
                .AppendLine("using System;")
                .AppendLine("using Microsoft.Data.Entity;")
                .AppendLine("using Microsoft.Data.Entity.Metadata;")
                .AppendLine("using Microsoft.Data.Entity.Relational.Migrations.Infrastructure;")
                .Append("using ").Append(contextType.Namespace).AppendLine(";")
                .AppendLine()
                .Append("namespace ").AppendLine(modelSnapshotNamespace)
                .AppendLine("{");
            using (builder.Indent())
            {
                builder
                    .Append("[ContextType(typeof(").Append(_code.Reference(contextType)).AppendLine("))]")
                    .Append("partial class ").Append(_code.Identifier(modelSnapshotName)).AppendLine(" : ModelSnapshot")
                    .AppendLine("{");
                using (builder.Indent())
                {
                    builder
                        .AppendLine("public override void BuildModel(ModelBuilder builder)")
                        .AppendLine("{");
                    using (builder.Indent())
                    {
                        _modelGenerator.Generate(model, builder);
                    }
                    builder.AppendLine("}");
                }
                builder.AppendLine("}");
            }
            builder.AppendLine("}");

            return builder.ToString();
        }
        public void Generate_entity_type_with_single_composite_foreign_key()
        {
            var builder = new ModelBuilder();

            builder.Entity<Customer>(b =>
                {
                    b.Property(e => e.Id);
                    b.Property(e => e.Name);
                    b.Key(e => new { e.Id, e.Name });
                });

            builder.Entity<Order>(b =>
                {
                    b.Property(e => e.Id);
                    b.Property(e => e.CustomerId);
                    b.Property(e => e.CustomerName);
                    b.Key(e => e.Id);
                });

            builder.Entity<Order>()
                .ForeignKeys(fks => fks.ForeignKey<Customer>(e => new { e.CustomerId, e.CustomerName }));

            var stringBuilder = new IndentedStringBuilder();
            new CSharpModelCodeGenerator().Generate(builder.Model, stringBuilder);

            Assert.Equal(
                @"var builder = new ModelBuilder();

builder.Entity(""Customer"", b =>
    {
        b.Property<int>(""Id"");
        b.Property<string>(""Name"");
        b.Key(""Id"", ""Name"");
    });

builder.Entity(""Order"", b =>
    {
        b.Property<int>(""CustomerId"");
        b.Property<string>(""CustomerName"");
        b.Property<int>(""Id"");
        b.Key(""Id"");
        b.ForeignKeys(fks => fks.ForeignKey(""Customer"", ""CustomerId"", ""CustomerName""));
    });

return builder.Model;",
                stringBuilder.ToString());
        }
        public void Generate_entity_type_with_multiple_foreign_keys_with_annotations()
        {
            var builder = new ModelBuilder();
            builder.Entity<Customer>(b =>
                {
                    b.Property(e => e.Id);
                    b.Property(e => e.Name);
                    b.Key(e => new { e.Id, e.Name });
                });

            builder.Entity<Order>(b =>
                {
                    b.Property(e => e.Id);
                    b.Property(e => e.CustomerId);
                    b.Property(e => e.CustomerName);
                    b.Property(e => e.ProductId);
                    b.Key(e => e.Id);
                });

            builder.Entity<Product>(b =>
                {
                    b.Property(e => e.Id);
                    b.Key(e => e.Id);
                });

            builder.Entity<Order>()
                .ForeignKeys(
                    fks =>
                        {
                            fks.ForeignKey<Customer>(e => new { e.CustomerId, e.CustomerName })
                                .Annotation("A1", "V1")
                                .Annotation("A2", "V2");
                            fks.ForeignKey<Product>(e => e.ProductId)
                                .Annotation("A3", "V3")
                                .Annotation("A4", "V4");
                        });

            var stringBuilder = new IndentedStringBuilder();
            new CSharpModelCodeGenerator().Generate(builder.Model, stringBuilder);

            Assert.Equal(
                @"var builder = new ModelBuilder();

builder.Entity(""Customer"", b =>
    {
        b.Property<int>(""Id"");
        b.Property<string>(""Name"");
        b.Key(""Id"", ""Name"");
    });

builder.Entity(""Order"", b =>
    {
        b.Property<int>(""CustomerId"");
        b.Property<string>(""CustomerName"");
        b.Property<int>(""Id"");
        b.Property<int>(""ProductId"");
        b.Key(""Id"");
        b.ForeignKeys(fks => 
            {
                fks.ForeignKey(""Customer"", ""CustomerId"", ""CustomerName"")
                    .Annotation(""A1"", ""V1"")
                    .Annotation(""A2"", ""V2"");
                fks.ForeignKey(""Product"", ""ProductId"")
                    .Annotation(""A3"", ""V3"")
                    .Annotation(""A4"", ""V4"");
            });
    });

builder.Entity(""Product"", b =>
    {
        b.Property<int>(""Id"");
        b.Key(""Id"");
    });

return builder.Model;",
                stringBuilder.ToString());
        }
        public virtual async Task<List<string>> GenerateAsync(
            [NotNull] ReverseEngineeringConfiguration configuration,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            Check.NotNull(configuration, nameof(configuration));

            CheckConfiguration(configuration);

            var resultingFiles = new List<string>();
            var providerAssembly = configuration.ProviderAssembly;
            var provider = GetProvider(providerAssembly);
            var metadataModel = GetMetadataModel(provider, configuration);

            var dbContextGeneratorModel = new DbContextGeneratorModel
            {
                ClassName = configuration.ContextClassName,
                Namespace = configuration.Namespace,
                ProviderAssembly = configuration.ProviderAssembly.FullName,
                ConnectionString = configuration.ConnectionString,
                MetadataModel = metadataModel
            };

            //TODO - check to see whether user has an override class for this in the current project first
            var dbContextCodeGenerator =
                provider.GetContextModelCodeGenerator(this, dbContextGeneratorModel);
            if (dbContextCodeGenerator == null)
            {
                throw new InvalidOperationException(
                    Strings.NoContextModelCodeGenerator(provider.GetType().FullName));
            }

            CheckOutputFiles(configuration.OutputPath, dbContextCodeGenerator.ClassName, metadataModel);

            var contextStringBuilder = new IndentedStringBuilder();
            dbContextCodeGenerator.Generate(contextStringBuilder);

            // output DbContext .cs file
            var dbContextFileName = dbContextCodeGenerator.ClassName + FileExtension;
            using (var sourceStream = new MemoryStream(Encoding.UTF8.GetBytes(contextStringBuilder.ToString())))
            {
                await OutputFile(configuration.OutputPath, dbContextFileName, sourceStream);
            }
            resultingFiles.Add(Path.Combine(configuration.OutputPath, dbContextFileName));

            foreach (var entityType in metadataModel.EntityTypes)
            {
                var entityTypeGeneratorModel = new EntityTypeGeneratorModel()
                {
                    EntityType = entityType,
                    Namespace = configuration.Namespace,
                    ProviderAssembly = configuration.ProviderAssembly.FullName,
                    ConnectionString = configuration.ConnectionString,
                };

                //TODO - check to see whether user has an override class for this in the current project first
                var entityTypeCodeGenerator =
                    provider.GetEntityTypeModelCodeGenerator(
                        this,
                        entityTypeGeneratorModel);
                if (entityTypeCodeGenerator == null)
                {
                    throw new InvalidOperationException(
                        Strings.NoEntityTypeModelCodeGenerator(provider.GetType().FullName));
                }

                var entityTypeStringBuilder = new IndentedStringBuilder();
                entityTypeCodeGenerator.Generate(entityTypeStringBuilder);

                // output EntityType poco .cs file
                using (var sourceStream = new MemoryStream(Encoding.UTF8.GetBytes(entityTypeStringBuilder.ToString())))
                {
                    var entityTypeFileName = entityType.Name + FileExtension;
                    await OutputFile(configuration.OutputPath, entityTypeFileName, sourceStream);
                    resultingFiles.Add(Path.Combine(configuration.OutputPath, entityTypeFileName));
                }
            }

            return resultingFiles;
        }
        public void Generate_model_snapshot_class()
        {
            var model = new Model();
            var entityType = new EntityType("Entity");

            entityType.SetKey(entityType.AddProperty("Id", typeof(int)));
            model.AddEntityType(entityType);

            var stringBuilder = new IndentedStringBuilder();
            new CSharpModelCodeGenerator().GenerateModelSnapshotClass("MyNamespace", "MyClass", model, stringBuilder);

            Assert.Equal(
                @"using Microsoft.Data.Entity.Metadata;
using Microsoft.Data.Entity.Migrations.Infrastructure;
using System;

namespace MyNamespace
{
    public class MyClass : ModelSnapshot
    {
        public override IModel Model
        {
            get
            {
                var builder = new ModelBuilder();
                
                builder.Entity(""Entity"", b =>
                    {
                        b.Property<int>(""Id"");
                        b.Key(""Id"");
                    });
                
                return builder.Model;
            }
        }
    }
}",
                stringBuilder.ToString());
        }
 public override void GenerateCode(
     MigrationCodeGenerator generator,
     IndentedStringBuilder stringBuilder)
 {
 }
        public override void GenerateModelSnapshotClass(
            string @namespace,
            string className,
            IModel model,
            IndentedStringBuilder stringBuilder)
        {
            Check.NotEmpty(className, "className");
            Check.NotEmpty(@namespace, "namespace");
            Check.NotNull(model, "model");
            Check.NotNull(stringBuilder, "stringBuilder");

            // TODO: Consider namespace ordering, for example putting System namespaces first
            foreach (var ns in GetNamespaces(model).OrderBy(n => n).Distinct())
            {
                stringBuilder
                    .Append("using ")
                    .Append(ns)
                    .AppendLine(";");
            }

            stringBuilder
                .AppendLine()
                .Append("namespace ")
                .AppendLine(@namespace)
                .AppendLine("{");

            using (stringBuilder.Indent())
            {
                stringBuilder
                    .Append("public class ")
                    .Append(className)
                    .AppendLine(" : ModelSnapshot")
                    .AppendLine("{");

                using (stringBuilder.Indent())
                {
                    stringBuilder
                        .AppendLine("public override IModel Model")
                        .AppendLine("{");

                    using (stringBuilder.Indent())
                    {
                        stringBuilder
                            .AppendLine("get")
                            .AppendLine("{");

                        using (stringBuilder.Indent())
                        {
                            Generate(model, stringBuilder);
                        }

                        stringBuilder
                            .AppendLine()
                            .AppendLine("}");
                    }

                    stringBuilder.AppendLine("}");
                }

                stringBuilder.AppendLine("}");
            }

            stringBuilder.Append("}");
        }
        public virtual string Create(bool ifNotExists)
        {
            var builder = new IndentedStringBuilder();

            if (ifNotExists)
            {
                builder.AppendLine("IF NOT EXISTS(SELECT * FROM [INFORMATION_SCHEMA].[TABLES] WHERE[TABLE_SCHEMA] = N'dbo' AND[TABLE_NAME] = '" + MigrationHistoryTableName + "' AND[TABLE_TYPE] = 'BASE TABLE')");
                builder.IncrementIndent();
            }

            builder
                .AppendLine("CREATE TABLE [dbo].[" + MigrationHistoryTableName + "] (");
            using (builder.Indent())
            {
                builder
                    .AppendLine("[MigrationId] nvarchar(150) NOT NULL,")
                    .AppendLine("[ContextKey] nvarchar(300) NOT NULL,")
                    .AppendLine("[ProductVersion] nvarchar(32) NOT NULL,")
                    .AppendLine("CONSTRAINT [PK_MigrationHistory] PRIMARY KEY ([MigrationId], [ContextKey])");
            }
            builder.Append(");");

            return builder.ToString();
        }
        protected virtual void GenerateEntityTypes(
            IReadOnlyList<IEntityType> entityTypes, IndentedStringBuilder stringBuilder)
        {
            foreach (var entityType in entityTypes)
            {
                stringBuilder.AppendLine();

                GenerateEntityType(entityType, stringBuilder);
            }
        }