internal static void ExecuteSqlScript(this SqlResourceInfo resource, SqlScriptsHistoryContext historyContext, DbContextTransaction packTran = null)
        {
            DbContextTransaction internalTran = null;

            if (packTran == null)
            {
                internalTran = historyContext.Database.BeginTransaction();
            }
            try {
                string[] commands = _regex
                                    .Split(resource.GetSqlScript())
                                    .Where(c => !string.IsNullOrWhiteSpace(c))
                                    .ToArray();
                foreach (var command in commands)
                {
                    historyContext.Database.ExecuteSqlCommand(command);
                }
                historyContext.SqlScriptsHistory.AddOrUpdate(h => h.ScriptName, new SqlScriptsHistorEntity()
                {
                    ScriptName = resource.Path, Hash = resource.Hash, ExecutionDateUtc = DateTime.UtcNow
                });
                historyContext.SaveChanges();

                if (internalTran != null)
                {
                    internalTran.Commit();
                }
            } finally {
                if (internalTran != null)
                {
                    internalTran.Dispose();
                }
            }
        }
        public static IEnumerable <SqlResourceInfo> ExecuteSqlScripts <TContext>(this DbMigrationsConfiguration <TContext> config, TContext context, ScriptExecuteRule rule = ScriptExecuteRule.Modified, string packName = null) where TContext : DbContext
        {
            packName = (packName ?? String.Empty).Trim();
            var configType  = config.GetType();
            var startString = configType.Namespace + SqlResourceInfo.scriptFolderName + (string.IsNullOrWhiteSpace(packName) ? "" : packName + ".");

            var migrateCultures = new[] { "Default", GetResourceCultureName() };

            var resources = configType.Assembly.GetManifestResourceNames().Where(s => s.StartsWith(startString, StringComparison.InvariantCultureIgnoreCase) &&
                                                                                 s.EndsWith(".sql", StringComparison.InvariantCultureIgnoreCase)
                                                                                 ).Select(s => new SqlResourceInfo(configType, packName, s))
                            .Where(r => migrateCultures.Contains(r.CultureName, StringComparer.InvariantCultureIgnoreCase));

            using (var historyContext = new SqlScriptsHistoryContext(context.Database.Connection, false)) {
                InitializeDatabase(historyContext);
                historyContext.Database.CommandTimeout = (int)Math.Max(context.Database.CommandTimeout ?? 0, 120);
                var histories = historyContext.SqlScriptsHistory.Where(h => h.ScriptName.StartsWith(startString)).ToDictionary(h => h.ScriptName.ToLower(), h => h.Hash);

                DbContextTransaction packTran = null;
                switch (rule)
                {
                case ScriptExecuteRule.Modified:
                    resources = resources.Where(r => {
                        string hashVal;
                        return(!histories.TryGetValue(r.Path.ToLower(), out hashVal) || !hashVal.Equals(r.Hash, StringComparison.InvariantCultureIgnoreCase));
                    });
                    break;

                case ScriptExecuteRule.ModifiedPack:
                    if (!resources.Any(r => {
                        string hashVal;
                        return(!histories.TryGetValue(r.Path.ToLower(), out hashVal) || !hashVal.Equals(r.Hash, StringComparison.InvariantCultureIgnoreCase));
                    }))
                    {
                        resources = new SqlResourceInfo[] { };
                    }
                    else
                    {
                        packTran = historyContext.Database.BeginTransaction();
                    }
                    break;

                case ScriptExecuteRule.Once:
                    resources = resources.Where(r => !histories.ContainsKey(r.Path.ToLower()));
                    break;
                    //default: // do nothing on ScriptExecuteRule.Always
                }

                resources = resources
                            .OrderBy(r => r.CultureName == "Default" ? 0 : 1)
                            .ThenBy(r => r.FolderName + "z")
                            .ThenBy(r => r.Path).ToArray();
                try {
                    foreach (var resourceInfo in resources.ToArray())
                    {
                        resourceInfo.ExecuteSqlScript(historyContext, packTran);
                    }
                    if (packTran != null)
                    {
                        packTran.Commit();
                    }
                } finally {
                    if (packTran != null)
                    {
                        packTran.Dispose();
                    }
                }
                return(resources);
            }
        }