Skip to content

Instantly share code, notes, and snippets.

@maximejobin
Last active April 29, 2019 15:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maximejobin/7f576c1973da1c573762c2feeeb75401 to your computer and use it in GitHub Desktop.
Save maximejobin/7f576c1973da1c573762c2feeeb75401 to your computer and use it in GitHub Desktop.
Entity framework 6.1 - Enable column ordering and where clause in an index
using System.Data.Entity.Migrations;
internal sealed class MyConfiguration : DbMigrationsConfiguration<MyContext>
{
/// <summary>
/// Constructor
/// </summary>
public MyConfiguration()
{
// Other stuff here...
// Index/Unique custom generation (Ascending and Descending)
SetSqlGenerator("System.Data.SqlClient", new CustomSqlServerMigrationSqlGenerator());
}
}
using System;
using System.Data.Entity.Migrations.Model;
using System.Data.Entity.SqlServer;
using System.Text;
/// <summary>
/// Entity framework custom code generator
///
/// Copyright 2019 - Maxime Jobin - All rights reserved
///
/// You can use and share this code as long as the copyright remains intact in your code.
/// </summary>
namespace S2B.APS.EntityFramework
{
// Inspired by some code from Rowan Miller
// http://romiller.com/2012/01/16/customizing-code-first-migrations-provider/
public class CustomSqlServerMigrationSqlGenerator : SqlServerMigrationSqlGenerator
{
protected override void Generate(CreateIndexOperation createIndexOperation)
{
using (var writer = Writer())
{
var sql = new StringBuilder();
sql.Append("CREATE ");
if (createIndexOperation.IsUnique)
{
sql.Append("UNIQUE ");
}
if (createIndexOperation.IsClustered)
{
sql.Append("CLUSTERED ");
}
else
{
sql.Append("NONCLUSTERED ");
}
string name = createIndexOperation.Name;
string[] sorts = {};
string where = null;
if (createIndexOperation.Name.Contains(":"))
{
var parts = createIndexOperation.Name.Split(':');
if (parts.Length >= 1)
{
name = parts[0];
}
if (parts.Length >= 2)
{
sorts = parts[1].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
}
if (parts.Length >= 3)
{
where = parts[2];
}
}
sql.Append("INDEX ");
sql.Append(Quote(name));
sql.Append(" ON ");
sql.Append(Name(createIndexOperation.Table));
sql.Append("(");
// Sort columns
string fields = "";
if (sorts.Length == 0 || sorts.Length == createIndexOperation.Columns.Count)
{
for (int i=0 ; i<createIndexOperation.Columns.Count ; i++)
{
string sort = "ASC";
if (sorts.Length == 0)
{
// Nothing to do
}
else if (sorts[i] != "ASC" && sorts[i] != "DESC")
{
throw new Exception(string.Format("Expected sort for {0} is 'ASC' or 'DESC. Received: {1}", name, sorts[i]));
}
else
{
sort = sorts[i];
}
fields = fields + Quote(createIndexOperation.Columns[i]) + " " + sort + ",";
}
fields = fields.Substring(0, fields.Length - 1);
}
sql.Append(fields);
sql.Append(")");
// WHERE
if (string.IsNullOrWhiteSpace(where) == false)
{
sql.Append(" WHERE ");
sql.Append(where);
}
writer.Write(sql.ToString());
Statement(writer);
}
}
}
}
/**
* Entity object
*/
public class MyObject {
public int Id { get; set; }
public string Type { get; set; }
public DateTime DateFor { get; set; }
public DateTime DateCreated { get; set; }
public string Value { get; set; }
}
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Infrastructure.Annotations;
using System.Data.Entity.ModelConfiguration;
namespace X
{
public class MyObjectMap : EntityTypeConfiguration<MyObject>
{
public MyObjectMap()
{
// Index name in 3 parts:
// 1st part: index name
// 2nd part: Columns order separated by commas [optional]
// 3rd part: WHERE clause of the index [optional]
var indexName = "IX_Table:ASC,DESC,DESC:Type IS NOT NULL";
this.Property(t => t.Type)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(new[]
{
new IndexAttribute(indexName) { Order = 1 }
}
)
);
this.Property(t => t.DateFor)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(new[]
{
new IndexAttribute(indexName) { Order = 2 }
}
)
);
this.Property(t => t.DateCreated)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(new[]
{
new IndexAttribute(indexName) { Order = 3 }
}
)
);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment