3

是否可以使用EF Code First Migrations的CreateIndex语法创建覆盖索引(*请参阅下文了解覆盖索引的含义)。EF代码优先:CreateIndex - 覆盖索引

例如,我可以在手动迁移创建一个简单的指标,像这样:

CreateIndex("RelatedProduct", "RelatedId"); 

它有一个名为“匿名参数”的最终参数,指定它可以处理任何潜在的供应商支持 - 但它不是清楚我如何确定支持是什么。这是可能的还是我需要诉诸平坦的SQL? *覆盖索引是RDB在叶节点中存储重复数据的地方,而不仅仅是指向主表的指针。它本质上是索引中列重新排序的表的重复,仅包含该类型搜索中最常用的列。

回答

7

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

CreateIndex现在不支持。您必须直接使用Sql,或者您可以检查EF的源代码,并在SQL生成器中将INCLUDE的支持添加到CreateIndex调用,CreateIndexOperation和相关的Generate方法中。

+0

是的,一个普通的醇”(非聚集)索引和覆盖索引之间的差通常是一个索引不存储数据,只是指向表的指针。覆盖索引额外存储一些列的副本。 http://stackoverflow.com/questions/609343/what-are-covering-indexes-and-covered-queries-in-sql-server在检查源代码时的良好调用,我会看看。 – 2013-02-15 01:19:53

+0

你是对的; anonymousArguments arg给了我希望,但是源代码只是将它们存储在一个Dictionary中,并且对它们不做任何事情 - 大概是将来的特性。它看起来合理地可能分叉源并且增加这个能力。 System.Data.Entity.Migrations.Sql.SqlServerMigrationSqlGenerator有一个保护虚拟无效生成(CreateIndexOperation createIndexOperation)的方法,该方法足以直接将其添加到。 – 2013-02-15 01:37:49

1

您不能使用CreateIndex调用来执行此操作,但您可以在不修改EF源的情况下从侧面提供您自己的替代方法。其核心是在手动迁移的你的向上()方法发射原始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(")"); 
}