使用Entity Framework创建数据库索引
说我有以下型号:
[Table("Record")] public class RecordModel { [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] [Display(Name = "Record Id")] public int RecordId { get; set; } [StringLength(150)] public string Name { get; set; } [Required] [StringLength(15)] public string IMEI { get; set; } }
是否可以通过使用属性,数据注释或模型中的某些内容向IMEI
列添加索引?
根据此链接: 使用Entity Framework 5.0通过数据注释创建索引,您应该编写某种扩展代码:
using System; [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)] public class IndexAttribute : Attribute { public IndexAttribute(string name, bool unique = false) { this.Name = name; this.IsUnique = unique; } public string Name { get; private set; } public bool IsUnique { get; private set; } }
和第二课:
using System.ComponentModel.DataAnnotations.Schema; using System.Data.Entity; using System.Linq; using System.Reflection; public class IndexInitializer : IDatabaseInitializer where T : DbContext { private const string CreateIndexQueryTemplate = "CREATE {unique} INDEX {indexName} ON {tableName} ({columnName})"; public void InitializeDatabase(T context) { const BindingFlags PublicInstance = BindingFlags.Public | BindingFlags.Instance; foreach (var dataSetProperty in typeof(T).GetProperties(PublicInstance).Where( p => p.PropertyType.Name == typeof(DbSet<>).Name)) { var entityType = dataSetProperty.PropertyType.GetGenericArguments().Single(); TableAttribute[] tableAttributes = (TableAttribute[])entityType.GetCustomAttributes(typeof(TableAttribute), false); foreach (var property in entityType.GetProperties(PublicInstance)) { IndexAttribute[] indexAttributes = (IndexAttribute[])property.GetCustomAttributes(typeof(IndexAttribute), false); NotMappedAttribute[] notMappedAttributes = (NotMappedAttribute[])property.GetCustomAttributes(typeof(NotMappedAttribute), false); if (indexAttributes.Length > 0 && notMappedAttributes.Length == 0) { ColumnAttribute[] columnAttributes = (ColumnAttribute[])property.GetCustomAttributes(typeof(ColumnAttribute), false); foreach (var indexAttribute in indexAttributes) { string indexName = indexAttribute.Name; string tableName = tableAttributes.Length != 0 ? tableAttributes[0].Name : dataSetProperty.Name; string columnName = columnAttributes.Length != 0 ? columnAttributes[0].Name : property.Name; string query = CreateIndexQueryTemplate.Replace("{indexName}", indexName) .Replace("{tableName}", tableName) .Replace("{columnName}", columnName) .Replace("{unique}", indexAttribute.IsUnique ? "UNIQUE" : string.Empty); context.Database.CreateIfNotExists(); context.Database.ExecuteSqlCommand(query); } } } } } }
在它之后你可以这样使用你的index
:
[Required] [Index("IMEIIndex", unique: true)] [StringLength(15)] public string IMEI { get; set; }
更新:自EF 6.1发布以来。 (2014年3月17日)确实有[Index]
属性可用。
function如下:
[Index("IMEIIndex", IsUnique = true)] public string IMEI { get; set; }
开箱即用。
PS:其他属性是Order
和IsClustered
。
根据这个链接: http : //blogs.msdn.com/b/adonet/archive/2014/02/11/ef-6-1-0-beta-1-available.aspx
它将在EF 6.1中作为标准DataAnnotation属性提供。
IndexAttribute允许通过在Code First模型中的属性(或属性)上放置[Index]属性来指定索引。 然后,Code First将在数据库中创建相应的索引。