EF Code First:CreateIndex - 覆盖索引

时间:2013-02-14 18:51:43

标签: entity-framework indexing ef-code-first ef-migrations covering-index

是否可以使用EF Code First Migrations的CreateIndex语法创建覆盖索引(*参见下面的覆盖索引)。

例如,我可以在手动迁移中创建一个简单的索引,如下所示:

CreateIndex("RelatedProduct", "RelatedId");

它有一个名为“匿名参数”的最终参数,它指定它可以处理底层提供程序支持的任何内容 - 但是我不清楚我如何确定支持是什么。这是可能的还是我需要求助于平面SQL?

*覆盖索引是RDB在叶节点中存储重复数据的索引,而不仅仅是指向主表的指针。它本质上是由索引中的列重新排序的表的重复,仅包含该类型搜索中最常用的列。

2 个答案:

答案 0 :(得分:7)

我认为覆盖索引是非聚集索引,它涵盖了查询(因此它不需要任何额外的查找返回到表)。您描述的是此索引的附加功能,它允许您包括不属于叶级别的索引键的数据。

CreateIndex现在不支持。您必须直接使用Sql,或者您可以检查EF的源代码,并在{1}}中添加对CreateIndex调用,CreateIndexOperation和SQL Generator中相关Generate方法的支持

答案 1 :(得分:1)

您无法使用CreateIndex调用来执行此操作,但您可以从侧面提供自己的替代方案,而无需修改EF的来源。它的核心是在手动迁移的Up()方法中发出原始Sql,如:

// Build a string like
//@"create nonclustered index IX_IsPublished_OrderIndex
//on Project (IsPublished desc, OrderIndex asc)
//include [Key]"
var sb = new StringBuilder();
sb.Append("create nonclustered index [")
.Append(Name)
.Append("] on [")
.Append(Table)
.Append("] (")
.Append(String.Join(", ", Columns
    .Select(col => "[" + col.Name + "] " + (col.IsAsc ? "asc" : "desc"))
))
.Append(")");

if (Include != null && Include.Length > 0)
{
    sb.Append(" include (")
    .Append(String.Join(", ", Include.Select(c => "[" + c + "]")))
    .Append(")");
}