2011-02-14 57 views
30

有没有办法让EF CTP5在创建一个模式时创建一个索引?首先添加带实体框架代码的索引(CTP5)

更新:请参阅here了解EF 6.1如何处理此问题(如下面的juFo所指出的那样)。

+1

您可以在此投票选择此功能:http://connect.microsoft.com/VisualStudio/feedback/details/624575/index-attribute-in-ef-code-first – 2011-12-09 13:07:18

+2

@ vasek7:MS回应并说您应该在这里投票,而不是:http://data.uservoice.com/forums/72025-entity-framework-feature-suggestions/suggestions/2231176-indexattribute(我加我的+3) – mpen 2012-04-15 22:29:46

+0

看到解决方案在这里:http://stackoverflow.com/a/23055838/187650 – juFo 2014-07-20 17:44:09

回答

31

您可以采取数据库类,它允许对数据库执行原始的SQL命令,利用新CTP5的ExecuteSqlCommand方法。

为此目的而调用SqlCommand方法的最佳位置是在自定义初始化程序类中覆盖的Seed方法内。例如:

protected override void Seed(EntityMappingContext context) 
{ 
    context.Database.ExecuteSqlCommand("CREATE INDEX IX_NAME ON ..."); 
} 
+0

真是个好主意!那么我认为除此之外还没有内置的支持? – 2011-02-14 18:53:15

17

正如一些评论,以Mortezas提到的回答有,如果你使用一个迁移的CreateIndex/DropIndex方法。

但是,如果您处于“调试”/开发模式,并且一直在更改模式,并且每次使用Morteza答案中提到的示例时都重新创建数据库。

为了让它更容易一点,我写了一个非常简单的扩展方法,使其强烈类型化,作为灵感,我想与任何阅读此问题的人分享,也许会喜欢这种方法。只需改变它以符合您的需求和命名索引的方式。

You use it like this: context.Database.CreateUniqueIndex<User>(x => x.Name); 

public static void CreateUniqueIndex<TModel>(this Database database, Expression<Func<TModel, object>> expression) 
    { 
     if (database == null) 
      throw new ArgumentNullException("database"); 

     // Assumes singular table name matching the name of the Model type 

     var tableName = typeof(TModel).Name; 
     var columnName = GetLambdaExpressionName(expression.Body); 
     var indexName = string.Format("IX_{0}_{1}", tableName, columnName); 

     var createIndexSql = string.Format("CREATE UNIQUE INDEX {0} ON {1} ({2})", indexName, tableName, columnName); 

     database.ExecuteSqlCommand(createIndexSql); 
    } 

    public static string GetLambdaExpressionName(Expression expression) 
    { 
     MemberExpression memberExp = expression as MemberExpression; 

     if (memberExp == null) 
     { 
      // Check if it is an UnaryExpression and unwrap it 
      var unaryExp = expression as UnaryExpression; 
      if (unaryExp != null) 
       memberExp = unaryExp.Operand as MemberExpression; 
     } 

     if (memberExp == null) 
      throw new ArgumentException("Cannot get name from expression", "expression"); 

     return memberExp.Member.Name; 
    } 

更新:从6.1版本及以后有一个[索引]属性可用。

欲了解更多信息,请参阅http://msdn.microsoft.com/en-US/data/jj591583#Index

2

此功能应通过数据注释和流利的API,在不久的将来推出。微软增加了它纳入其积压:

http://entityframework.codeplex.com/workitem/list/basic?keywords=DevDiv [Id=87553]

在那之前,你需要一个自定义使用种子法初始化器类执行SQL创建唯一索引,如果你是使用代码优先迁移,创建新的迁移以添加唯一索引,并在您的UpDown方法中使用CreateIndexDropIndex方法进行迁移以创建和删除索引。

相关问题