Last active
April 29, 2019 15:33
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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; } | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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