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 - 覆盖索引的主要内容,如果未能解决你的问题,请参考以下文章

ASP MVC 数据库优先 - 刷新 EF 实体框架时丢失所有验证

EF 4.1 代码优先关系表

骑士。 EF 代码优先迁移

EF6 使用列默认值创建代码优先表

EF之Code First代码优先

EF - 代码优先 - SQL 默认值 getdate() 给出错误