4

I am aware of this, which states that it is not possible to create a primary key with non clustered index via code first. Is this still the case?

Ideally, I would like to specify via EntityTypeConfiguration, that my primary key (Guid) has a non-clustered index and there is another column (int) with a clustered index.

Community
  • 1
  • 1
cs0815
  • 16,751
  • 45
  • 136
  • 299
  • Possible duplicate of [In Entity Framework 6.1, how can I use the IndexAttribute to define a clustered index?](http://stackoverflow.com/questions/22813137/in-entity-framework-6-1-how-can-i-use-the-indexattribute-to-define-a-clustered) – Korayem Apr 18 '16 at 19:20
  • @Korayem who says I use EF 6.1? – cs0815 Apr 19 '16 at 07:56
  • you tagged the question entity-framework-6 so I presumed 6.1. I edited the title and removed the duplicate request. – Korayem Apr 19 '16 at 08:35
  • 1
    Very much appreciated. – cs0815 Apr 19 '16 at 08:39
  • For the benefit of searchers, I created a related post for EntityFramework Core, which also enables this - http://stackoverflow.com/questions/41004292/create-a-non-clustered-index-in-entity-framework-core – JsAndDotNet Dec 07 '16 at 09:44

2 Answers2

5

AFAIK this is not possible with EntityTypeConfiguration. However you can do this with Code-First migrations. Working example:

public class Product
{
    public Guid Id
    { get; set; }

    public int Price
    { get; set; }
}

class AppDbContext : DbContext
{
    public DbSet<Product> Products
    { get; set; }
}

public partial class InitialCreate : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "dbo.Products",
            c => new
                {
                    Id = c.Guid(nullable: false),
                    Price = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.Id, clustered: false)
            .Index(t => t.Price, clustered: true);

    }

    public override void Down()
    {
        DropIndex("dbo.Products", new[] { "Price" });
        DropTable("dbo.Products");
    }
}

Result:

CREATE TABLE [dbo].[Products] (
    [Id]    UNIQUEIDENTIFIER NOT NULL,
    [Price] INT              NOT NULL,
    CONSTRAINT [PK_dbo.Products] PRIMARY KEY NONCLUSTERED ([Id] ASC)
);

GO
CREATE CLUSTERED INDEX [IX_Price]
    ON [dbo].[Products]([Price] ASC);
ranquild
  • 1,799
  • 1
  • 16
  • 25
  • Thanks. I have found something along those lines. I presume this is still the case then. I wait a bit longer before I accept. – cs0815 Jul 17 '15 at 18:20
0

You can also do this with your OnModelCreating method like so:

modelBuilder.Entity(entityTypeName)
    .HasKey(nameof(ClassName.Id))
    .ForSqlServerIsClustered(false);
Tyler Findlay
  • 607
  • 1
  • 4
  • 19