1
  1. I use Fluent API. I don't like annotations.

  2. I like to always use an autoincrement as my primary key, in all of my tables.

  3. Some of my tables require that two columns, X and Y (where X is not the autoincrement key and Y is not the autoincrement key) have to be unique, ie: there can't be another row such that it has X1=X2 and Y1=Y2. If I wasn't using an autoincrement key, I would simply make these two the key, like this:

        modelBuilder.Entity<Foo>()
            .HasKey(t => new { t.X, t.Y })
            .ToTable("Foos");
    

    But, as I said in (2), I'm using autoincrement primary keys

        modelBuilder.Entity<Foo>()
            .HasKey(t => t.someLongId)
            .ToTable("Foos");
    

How can I achieve this composite uniqueness in Fluent API?

This is what I want to achieve, written in SQL:

CREATE  TABLE `Foos` (
  `ID` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT ,
  ...
  PRIMARY KEY (`ID`),
  UNIQUE KEY (`X`, `Y`) 
);
Aydin
  • 15,016
  • 4
  • 32
  • 42
sports
  • 7,851
  • 14
  • 72
  • 129

2 Answers2

2

You can achieve this using the 'HasColumnAnnotation(...)' method and applying an IndexAnnotation > IndexAttribute.

modelBuilder.Entity<Foo>() 
            .Property(t => t.X) 
            .HasColumnAnnotation("X", new IndexAnnotation(new IndexAttribute("X") { IsUnique = true }));

You can find further information here (MSDN)

Aydin
  • 15,016
  • 4
  • 32
  • 42
  • this question was asked a long time ago. Still, I want to know if we can do the same thing using annotation? – tab87vn Apr 11 '16 at 09:25
1

Aydin's answer had the concept (IndexAnnotation and HasColumnAnnotation) but it wasn't involving the other columns. Here is a complete answer that worked for me:

modelBuilder
    .Entity<Foo>()
    .Property(t => t.X)
    .IsRequired()
    .HasMaxLength(60)
    .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("IX_X_Y", 1) { IsUnique = true }));

modelBuilder
    .Entity<Foo>()
    .Property(t => t.Y)
    .IsRequired()
    .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("IX_X_Y", 2) { IsUnique = true }));

That, supposing that X is string column and Y is not (just to show how .HasMaxLength(60) can be used in the string column)

I will accept Aydin's answer though.

sports
  • 7,851
  • 14
  • 72
  • 129
  • Also I should mention that this question is quite similar (he wanted a key though, so is not a duplicate): http://stackoverflow.com/questions/21573550/entity-framework-6-setting-unique-constraint-with-fluent-api/23155759#23155759 – sports Oct 09 '14 at 16:49