Basing on Viktor's answer I come up with solution creating this code automatically.
Final migration file should not use CreateIndex
method but the one I named CreateIndexNullable
. This method I created in DbMigrationEx
which extends DbMigration
protected void CreateIndexNullable(string table, string column, string name)
{
Sql($@"CREATE UNIQUE NONCLUSTERED INDEX [{name}] ON {table}([{column}] ASC) WHERE([{column}] IS NOT NULL);");
}
How to change migration class code?
In Configuration
class which is created in Migration folder I set
CodeGenerator = new CSharpMigrationCodeGeneratorIndexNullable();
My CSharpMigrationCodeGeneratorIndexNullable
class extends CSharpMigrationCodeGenerator
.
I'm not gonna show exact class content, I'll just present the idea.
Basing on CSharpMigrationCodeGenerator
content I overrode some methods. The Entity Framework project is available at https://github.com/aspnet/EntityFramework6.
To change migration class to DbMigrationEx
I used method
Generate(IEnumerable<MigrationOperation> operations, string @namespace, string className)
The only thing that needs change is
WriteClassStart(
@namespace, className, writer, "DbMigration", designer: false,
namespaces: GetNamespaces(operations));
To change migration method to CreateIndexNullable
I used method
Generate(CreateIndexOperation createIndexOperation, IndentedTextWriter writer)
You need to change line
writer.Write("CreateIndex(");
Also
WriteIndexParameters(createIndexOperation, writer);
to
writer.Write(", ");
writer.Write(Quote(createIndexOperation.Name));
But how to know if index must be nullable?
createIndexOperation
paramter contains index information. I was not able to modify CreateIndexOperation
creating, but its Table
, Name
and Columns
properties could be enough to get to fields in entity class and get Index
attribute which can be extended.