Is it possible using EF Fluent API to configure a Discriminator column and another string column to be part of a unique index constraint?
I have a list of identifiers, where the identifiers can be of different types. Each identifier has a property of type string which holds the identifying string.
A customer in my case can ha different identifiers. But there can only be one identifier with unique string per discriminator.
Abstract class defining a identifier type
public abstract class CustomerIdentifier : Entity<int>
{
public string Identifier { get; set; }
}
Concrete class derived from CustomerIdentifier
class NationalIdNumberIdentifier : CustomerIdentifier
{
}
I've managed to configure index for the string column using the answer here, Unique Key constraints for multiple columns in Entity Framework as follows
class CustomerIdentifierMap : EntityTypeConfiguration<CustomerIdentifier>
{
public CustomerIdentifierMap()
{
Property(p => p.Identifier).HasMaxLength(100).IsRequired().HasUniqueIndexAnnotation("UQ_IdentifierPerDiscriminator", 0);
}
}
I need to somehow add another line here specifiying that the discrimnator should be included in the unique index constraint.
Actually it can be done in EF 6. Below is an example that uses the primary key to create a unique index.
internal class DiscriminatorServerMigrationSqlGenerator : SqlServerMigrationSqlGenerator
{
const string DiscriminatorColumnName = "Discriminator";
protected override void Generate(CreateTableOperation op)
{
base.Generate(op);
if (op.Columns.Any(x => x.Name == DiscriminatorColumnName))
{
if (op.PrimaryKey != null && op.PrimaryKey.Columns.Any())
{
CreateDiscriminatorIndex(op.Name, true, op.PrimaryKey.Columns.ToArray());
}
else
{
CreateDiscriminatorIndex(op.Name);
}
}
}
private void CreateDiscriminatorIndex(string tableName, bool isUnique = false, params string[] columns)
{
var cols = "[Discriminator]";
if (columns.Length > 0)
{
cols += ", " + string.Join(", ", columns.Select(x => "[" + x + "]"));
}
var unique = isUnique ? "UNIQUE" : "";
using (var writer = Writer())
{
var str = $@"
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_Discriminator' AND object_id = OBJECT_ID(N'{tableName}'))
EXECUTE('CREATE {unique} NONCLUSTERED INDEX [IX_Discriminator] ON {tableName} ({cols})')";
writer.WriteLine(str);
Statement(writer);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With