让 Entity Framework Code First 运行自定义SQL语句
using System; using System.Data; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Data.SqlClient; using System.IO; using System.Text.RegularExpressions; using System.Transactions; public class CreateDatabaseWithAspNetRegSql<TContext> : IDatabaseInitializer<TContext> where TContext : DbContext { public enum CreationStrategy { AlwaysCreate, CreateIfModelChanged } private readonly CreationStrategy _creationStrategy; public CreateDatabaseWithAspNetRegSql( CreationStrategy creationStrategy) { _creationStrategy = creationStrategy; } #region IDatabaseInitializer<Context> Members public void InitializeDatabase(TContext context) { bool dbExists; using (new TransactionScope(TransactionScopeOption.Suppress)) { dbExists = context.Database.Exists(); } if (dbExists) { if (_creationStrategy == CreationStrategy.CreateIfModelChanged && context.Database.CompatibleWithModel(false)) return; context.Database.Delete(); } CreateDatabase(context); DbInitializer.DoAspNetRegSql(context.Database); CreateTablesForModels(context); Seed(context); context.SaveChanges(); } #endregion #region Private/Protected Methods private static void CreateDatabase(TContext context) { var masterDbConnString = context.Database .Connection.ConnectionString .Replace(context.Database.Connection.Database, "master"); //TODO: Find way to create db in an agnostic way. using (var conn = new SqlConnection(masterDbConnString)) { conn.Open(); using (var cmd = conn.CreateCommand()) { cmd.CommandText = string.Format("CREATE DATABASE [{0}]", context.Database.Connection.Database); cmd.ExecuteNonQuery(); } } } private static void DoAspNetRegSql(Database database) { //TODO: This file name reference is a hack, //need a better way of handling this! ExecuteSqlSript(database, @"C:\Users\Ken\Documents\Visual Studio 2010\Projects\MVCSandbox\_Resources\aspnet_regsql.sql"); } protected static void ExecuteSqlSript (Database database, string scriptPath) { var conn = database.Connection; if (conn.State == ConnectionState.Closed) conn.Open(); var fullScript = File.ReadAllText( scriptPath); foreach (var command in Regex.Split(fullScript, @"\bGO\b")) { var cmd = conn.CreateCommand(); cmd.CommandText = command; try { cmd.ExecuteNonQuery(); } catch (Exception e) { throw new ApplicationException(e.Message + "\r\n\r\nCommand: " + command, e); } } } private static void CreateTablesForModels(TContext context) { var modelBuildoutScript = ((IObjectContextAdapter)context) .ObjectContext.CreateDatabaseScript(); RemoveTableCreationCommandsForTablesCreatedByAspNetRegSql(ref modelBuildoutScript); context.Database.ExecuteSqlCommand(modelBuildoutScript); } private static readonly Regex __aspNetCreateTableCommandFinder = new Regex(@"create table \[dbo\]\.\[aspnet_\w+\][^;]*;"); private static void RemoveTableCreationCommandsForTablesCreatedByAspNetRegSql (ref string script) { script = __aspNetCreateTableCommandFinder.Replace(script, string.Empty); } #endregion #region Public Methods protected virtual void Seed(TContext context) { } #endregion }
直接看代码~

浙公网安备 33010602011771号