question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Ability to specify database collation

See original GitHub issue

There is no way to do this at the moment. Database is created with default settings. It is not an issue on most cases, but there is a plenty of specific ones. For example, I have different collation on production server db, then on development machine.

After some research I’ve come up with workaround. Pretty ugly so far, but at least working

In Migrations\00000000000000_CreateIdentitySchema.cs add

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.Sql($"DECLARE @dbname sysname = db_name(); " +
    "EXEC('ALTER DATABASE [' + @dbname + '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE');" +
    "EXEC('ALTER DATABASE [' + @dbname + '] COLLATE Cyrillic_General_CI_AS');" +
    "EXEC('ALTER DATABASE [' + @dbname + '] SET MULTI_USER') ", suppressTransaction: true);
    ...
}

It is ok. But the connection is reset after execution of this first migration so I have to run in separately. I’ve come up with the following script (resetdb.cmd):

dotnet ef database update 00000000000000_CreateIdentitySchema
dotnet ef database update

So, there should be a proper way to do such things.

See also #6565

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:8
  • Comments:18 (9 by maintainers)

github_iconTop GitHub Comments

3reactions
cmanoliucommented, Mar 21, 2019

Hello everyone, for the moment, my solution is to derive from the SqlServerMigrationsSqlGenerator and override Generate(SqlServerCreateDatabaseOperation, IModel, MigrationCommandListBuilder)

    internal class CustomSqlServerMigrationsSqlGenerator : SqlServerMigrationsSqlGenerator
    {
        internal const string DatabaseCollationName = "SQL_Latin1_General_CP1_CI_AI";

        public CustomSqlServerMigrationsSqlGenerator(
            MigrationsSqlGeneratorDependencies dependencies,
            IMigrationsAnnotationProvider migrationsAnnotations)
        : base(dependencies, migrationsAnnotations)
        {
        }

        protected override void Generate(
            SqlServerCreateDatabaseOperation operation,
            IModel model,
            MigrationCommandListBuilder builder)
        {
            base.Generate(operation, model, builder);

            if (DatabaseCollationName != null)
            {
                builder
                    .Append("ALTER DATABASE ")
                    .Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Name))
                    .Append(" COLLATE ")
                    .Append(DatabaseCollationName)
                    .AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator)
                    .EndCommand(suppressTransaction: true);
            }
        }
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);
        optionsBuilder.ReplaceService<IMigrationsSqlGenerator, CustomSqlServerMigrationsSqlGenerator>();
    }

then used it in the DbContext by replacing the IMigrationsSqlGenerator service

public class MyDbContext : DbContext
{
    //...

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);
        optionsBuilder.ReplaceService<IMigrationsSqlGenerator, CustomSqlServerMigrationsSqlGenerator>();
    }

    //...
}
3reactions
mwzndevcommented, Jan 9, 2019

Well, I created an extension using some examples I found and I’ve come up with this.

    public static class MigrationBuilderExtensions
    {
        public static void SetDatabaseCollationToInsensitive(this MigrationBuilder builder)
        {
            builder.Sql("DECLARE @dbname sysname = db_name(); " +
                        "EXEC('ALTER DATABASE [' + @dbname + '] COLLATE SQL_Latin1_General_CP1_CI_AI');", true);
        }
    }

And after creating your first migration just add the information on the top.

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.SetDatabaseCollationToInsensitive();
}

It’s working by just using Update-Database, works for me for now.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Set or Change the Server Collation - SQL
The server collation acts as the default collation for all system databases that are installed with the instance of SQL Server, and also...
Read more >
Questions About SQL Server Collations You Were Too Shy ...
A collation is a configuration setting that determines how the database engine should treat character data at the server, database, or column ...
Read more >
SQL Server Collation
A collation defines bit patterns that represent each character in metadata of database. SQL Server supports storing objects that have different ...
Read more >
Understanding the COLLATE DATABASE_DEFAULT ...
COLLATE is a clause applied to character string expression or column for textual data types such as char, varchar, text, nchar, nvarchar, and ......
Read more >
How to fix the collation of a Microsoft SQL Server database
Firstly, create a new database as per the guidelines for your specific application. Ensure the collation is set correctly; as well as any...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found