在Entity Framework 6.1(非Core)中,如何使用IndexAttribute定义聚簇索引?

Fab*_*ied 18 c# indexing entity-framework entity-framework-6

实体框架6.1(代码优先)增加了通过添加索引的可能性IndexAttribute.该属性采用一个参数来指定索引应该是群集还是非群集.

同时,AFAIK,Entity Framework要求每个实体都有一个主键(用该注释KeyAttribute),并且该主键始终作为聚簇键创建.

因此,只要我的申请IndexAttributeIsClustered = true,我得到一个错误,因为由于键时,已经一个聚集索引.

那么,如何使用IndexAttribute?创建不是主键的聚簇索引?可用的IsClustered属性是IndexAttribute什么?

(有关更多上下文:我正在映射一个仅用于通过LINQ查询进行读取的表.我不需要实际插入,更新或删除该表中的实体.因此,我不需要主键理想情况下,我想要一个没有主键的表,但是有一个非唯一的聚簇索引,专为阅读而优化.)

编辑(2014-04-11):另请参阅https://entityframework.codeplex.com/workitem/2212.

Col*_*lin 9

表上只能有一个聚簇索引,默认情况下,Entity Framework/Sql Server将其放在主键上.

那么IsClustered索引上的属性有什么用呢?它不是主键?好问题!(1)

这个班:

public class Blog
{
    [Key()]
    public int Id { get; set; }

    [MaxLength(256)]//Need to limit size of column for clustered indexes
    public string Title { get; set; }

    [Index("IdAndRating", IsClustered = true)]
    public int Rating { get; set; }

}
Run Code Online (Sandbox Code Playgroud)

将生成此迁移:

    public override void Up()
    {
        CreateTable(
            "dbo.Blogs",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    Title = c.String(maxLength: 256),
                    Rating = c.Int(nullable: false),
                });
            .PrimaryKey(t => t.Id)
            .Index(t => t.Rating, clustered: true, name: "IdAndRating");
    }
Run Code Online (Sandbox Code Playgroud)

改变迁移到此:

    public override void Up()
    {
        CreateTable(
            "dbo.Blogs",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    Title = c.String(maxLength: 256),
                    Rating = c.Int(nullable: false),
                });

        CreateIndex("dbo.Blogs", 
                    new[] { "Rating", "Title" }, 
                    clustered: true, 
                    name: "IdAndRating");

    }
Run Code Online (Sandbox Code Playgroud)

这应该创建没有主键但在其他列上使用聚簇索引的表

编辑 在您不需要插入,更新或删除数据的场景中,您不需要一个完整的实体,您可以使用原始SQL查询来填充类.您需要将自己的sql添加到迁移中以创建表,因为EF不会自动化它,但这意味着您可以根据需要创建表和索引.


小智 5

您可以从SqlServerMigrationSqlGenerator派生自己的类并在那里更改pk创建:

public class NonClusteredPrimaryKeySqlMigrationSqlGenerator : SqlServerMigrationSqlGenerator
{
    protected override void Generate(System.Data.Entity.Migrations.Model.AddPrimaryKeyOperation addPrimaryKeyOperation)
    {
        addPrimaryKeyOperation.IsClustered = false;
        base.Generate(addPrimaryKeyOperation);
    }

    protected override void Generate(System.Data.Entity.Migrations.Model.CreateTableOperation createTableOperation)
    {
        createTableOperation.PrimaryKey.IsClustered = false;
        base.Generate(createTableOperation);
    }

    protected override void Generate(System.Data.Entity.Migrations.Model.MoveTableOperation moveTableOperation)
    {
        moveTableOperation.CreateTableOperation.PrimaryKey.IsClustered = false;
        base.Generate(moveTableOperation);
    }
Run Code Online (Sandbox Code Playgroud)

完整示例 https://entityframework.codeplex.com/workitem/2163