EF 代码优先:CreateIndex - 覆盖索引
Posted
技术标签:
【中文标题】EF 代码优先:CreateIndex - 覆盖索引【英文标题】:EF Code First: CreateIndex - Covering Index 【发布时间】:2013-02-14 18:51:42 【问题描述】:是否可以使用 EF Code First 迁移的 CreateIndex 语法来创建覆盖索引(*请参阅下文了解覆盖索引是什么)。
例如,我可以像这样在手动迁移中创建一个简单的索引:
CreateIndex("RelatedProduct", "RelatedId");
它有一个名为“匿名参数”的最终参数,指定它可以处理底层提供程序支持的任何内容 - 但目前尚不清楚我如何确定该支持是什么。这是可能的还是我需要求助于平面 SQL?
*覆盖索引是 RDB 将重复数据存储在叶节点中的索引,而不仅仅是指向主表的指针。它本质上是由索引中的列重新排序的表的副本,仅包含该类型搜索中最常用的列。
【问题讨论】:
【参考方案1】:我认为覆盖索引是覆盖查询的非聚集索引(因此它不需要对表进行任何额外的查找)。您所描述的是此类索引的附加功能,它允许您在叶级别包含不属于索引键的数据。
CreateIndex
现在不支持。您必须直接使用Sql
,或者您可以查看EF 的源代码并将对INCLUDE
的支持添加到SQL 生成器中的CreateIndex
调用、CreateIndexOperation
和相关的Generate
方法中。
【讨论】:
是的,普通 ol'(非聚集)索引和覆盖索引之间的区别是索引通常不存储数据,只存储指向表的指针。覆盖索引还存储了一些列的副本。 ***.com/questions/609343/…查源好电话,我去看看。 你说得对; anonymousArguments arg 给了我希望,但源只是将这些存储在字典中并且对它们不做任何事情 - 大概是未来的功能。但是,似乎可以合理地分叉源并添加此功能。 System.Data.Entity.Migrations.Sql.SqlServerMigrationSqlGenerator 有一个方法 protected virtual void Generate(CreateIndexOperation createIndexOperation) 看起来很简单,可以添加它。【参考方案2】:您不能使用 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(")");
【讨论】:
以上是关于EF 代码优先:CreateIndex - 覆盖索引的主要内容,如果未能解决你的问题,请参考以下文章