Skip to content

Instantly share code, notes, and snippets.

@dschenkelman
Created May 9, 2014 04:51
Show Gist options
  • Save dschenkelman/22a6758fdf6818b26702 to your computer and use it in GitHub Desktop.
Save dschenkelman/22a6758fdf6818b26702 to your computer and use it in GitHub Desktop.
Creating Indexes via Data Annotations with Entity Framework 5.0
using System.Collections.Generic;
using System.Data.Entity;
public class CompositeDatabaseInitializer<T> : IDatabaseInitializer<T> where T : DbContext
{
private readonly List<IDatabaseInitializer<T>> initializers;
public CompositeDatabaseInitializer(params IDatabaseInitializer<T>[] databaseInitializers)
{
this.initializers = new List<IDatabaseInitializer<T>>();
this.initializers.AddRange(databaseInitializers);
}
public void InitializeDatabase(T context)
{
foreach (var databaseInitializer in this.initializers)
{
databaseInitializer.InitializeDatabase(context);
}
}
public void AddInitializer(IDatabaseInitializer<T> databaseInitializer)
{
this.initializers.Add(databaseInitializer);
}
public void RemoveInitializer(IDatabaseInitializer<T> databaseInitializer)
{
this.initializers.Remove(databaseInitializer);
}
}
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
public class Customer
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[Index("NameIndex", unique: true)]
[MaxLength(128)]
public string Name { get; set; }
}
[Table("Clients")]
public class Customer
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[Index("NameIndex", unique: true)]
[MaxLength(128)]
[Column("CustomerName")]
public string Name { get; set; }
}
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<T> : IDatabaseInitializer<T> 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);
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment