让 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
}


直接看代码~

posted @ 2012-11-03 17:20  □『孤獨~寂  阅读(971)  评论(0)    收藏  举报