Add discriminator column as part of a unique index in Entity Framework

Is it possible using the EF Fluent API to customize the Discriminator column and another row column to be part of a unique index constraint?

I have a list of identifiers, where identifiers can be of different types. Each identifier has a property of type string, which contains an identification string.

The client in my case may have different identifiers. But there can only be one identifier with a unique string per discriminator.

An abstract class defining the type of identifier

public abstract class CustomerIdentifier : Entity<int> { public string Identifier { get; set; } } 

A specific class derived from CustomerIdentifier

  class NationalIdNumberIdentifier : CustomerIdentifier { } 

I managed to set up the index for the row column using the answer here, Unique key constraints for multiple columns in the 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 that indicates that the discriminator should be included in the unique index constraint.

+5
source share
3 answers

Unfortunately, it is not supported in EF 6 and can be included in EF 7 according to the column "Support for the discriminator column, which is part of the main key" https://entityframework.codeplex.com/workitem/2420 .

You can vote for him to push him to the list of priorities.

+1
source

This can actually be done in EF 6. The following is an example that uses a 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); } } } 
+2
source

EF 7 now has support for this using the free API:

 modelBuilder.Entity<User>() .HasIndex("EmailAddress", "Discriminator") .HasName("UQ_EmailAddress") .IsUnique(); 
-1
source

Source: https://habr.com/ru/post/1211926/


All Articles