Last active
August 29, 2015 13:56
-
-
Save sinelaw/9084984 to your computer and use it in GitHub Desktop.
Super-hacky workaround for missing TVF support in EF code first, using an interceptor to rewrite a table name as a TVF function call
This file contains 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.Collections.Generic; | |
using System.Data; | |
using System.Data.Common; | |
using System.Data.Entity; | |
using System.Data.Entity.Infrastructure.Interception; | |
using System.Data.Entity.ModelConfiguration; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Text; | |
using System.Text.RegularExpressions; | |
using System.Threading.Tasks; | |
namespace Shamespace | |
{ | |
// Example usage - implementation is below the Program class | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var module = new DataExportModule(); | |
module.Initialize(new Keywords()); | |
DbInterception.Add(new TVFInterceptor(new Guid("12345678-1234-1234-1234-123456789012"))); | |
using (var entities = new EntitiesWithSecuredFunction("Entities")) | |
{ | |
Debug.WriteLine("Count = " + entities.MyTableValuedFunction.Count().ToString()); | |
} | |
} | |
} | |
public class MyTableValuedFunction | |
{ | |
public int SomeEntityId { get; set; } | |
} | |
public class MyTableValuedFunction_Map :EntityTypeConfiguration<MyTableValuedFunction> | |
{ | |
public MyTableValuedFunction_Map() | |
{ | |
this.ToTable("MyTableValuedFunction" + TVFInterceptor.TVFSuffix); | |
this.HasKey(x => x.SomeEntityId); | |
this.Property(t => t.SomeEntityId).IsRequired().HasColumnName("SomeEntityId"); | |
} | |
} | |
public class EntitiesWithSecuredFunction : Entities | |
{ | |
public EntitiesWithSecuredFunction(string nameOrConnectionString) : base(nameOrConnectionString) { } | |
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder) | |
{ | |
base.OnModelCreating(modelBuilder); | |
modelBuilder.Configurations.Add(new MyTableValuedFunction_Map()); | |
} | |
public DbSet<MyTableValuedFunction> MyTableValuedFunction { get; set; } | |
} | |
public class TVFInterceptor : System.Data.Entity.Infrastructure.Interception.IDbCommandInterceptor | |
{ | |
public TVFInterceptor(params object[] parameters) | |
{ | |
this._parameters = parameters; | |
} | |
public const string TVFSuffix = "_TVFInterceptorPrefix_"; | |
private object[] _parameters; | |
#region IDbCommandInterceptor Members | |
public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext) { } | |
public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext) { } | |
public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) { } | |
public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) | |
{ | |
UpdateCommand(command); | |
} | |
public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext) { } | |
public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext) | |
{ | |
UpdateCommand(command); | |
} | |
#endregion | |
#region Protected Methods | |
private void UpdateCommand(DbCommand command) | |
{ | |
var text = command.CommandText; | |
var parameters = this._parameters.Select(x => { | |
var param = command.CreateParameter(); | |
param.Value = x; | |
command.Parameters.Add(param); | |
return param; | |
}); | |
Debug.WriteLine("Original command: ", command.CommandText); | |
command.CommandText = text.Replace(TVFSuffix + "]", "](" + String.Join(", ", parameters.Select(x => "@" + x.ParameterName)) + ")"); | |
Debug.WriteLine("Modified command: ", command.CommandText); | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment