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.