Elmah和实体框架DropCreateDatabaseAlways

时间:2014-05-03 16:18:28

标签: c# asp.net-mvc entity-framework elmah

我有一个使用ASP.NET MVC和Entity Framework 6的应用程序。

目前,我在本地使用DropCreateDatabaseAlways数据库初始化程序,以便于测试和调试。我想配置应用程序以使用Elmah记录异常,但尚未成功。理想情况下,我希望Elmah在与现有应用程序数据库不同的数据库中登录。以下是我到目前为止所尝试的内容:

  1. 从Nuget安装Elmah和Elmah.Mvc
  2. 在web.config中,添加errorLog部分以指定连接到Elmah的连接字符串(尚未创建)

    <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="ElmahConnection" />
    
  3. 在web.config中为Elmah添加另一个连接字符串:

    <connectionStrings>    
    <add name="OTEConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\OTE.mdf;Initial Catalog=OTE;Integrated Security=True" providerName="System.Data.SqlClient" />
    <add name="ElmahConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\Elmah.mdf;Initial Catalog=Elmah;Integrated Security=True" providerName="System.Data.SqlClient" />
    

  4. OTEConnection是我现有的Entity Framework连接字符串。 当我运行它时,我收到错误:

    Cannot attach the file '{AbsolutePath}\App_Data\Elmah.mdf' as database 'Elmah'.
    

    有谁知道为什么我有这个错误?如果不可能将Elmah放在单独的数据库中,那么每次实体框架删除并创建新数据库时,我应该如何创建Elmah表?我想我需要创建一个继承自DropCreateDatabaseAlways的新类并重写方法InitializeDatabase?

    非常感谢

1 个答案:

答案 0 :(得分:1)

最后通过创建一个自定义类来执行脚本,以便在调用DropCreateDatabaseAlways时为Elmah创建表(基于此处的答案:http://social.msdn.microsoft.com/Forums/en-US/a0e09e12-4530-4148-a937-48d9bbf25a47/get-aspnet-membershiprole-working-with-dropcreatedatabasealways?forum=adodotnetentityframework

    public class ElmahDbInitializer
{        
    public static void RunScript()
    {
        SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["OTEConnection"].ConnectionString);

        string scriptText = GetScript();
        string[] commandTexts = GetScriptSections(scriptText);
        Array.ForEach(commandTexts, s => RunSection(s, con));
    }

    private static string GetScript()
    {
        using (StreamReader reader = new StreamReader(GetExecutingDirectory() + "\\SetUp\\ELMAH-1.2-db-SQLServer.sql"))
        {
            return reader.ReadToEnd();
        }            
    }

    private static string GetExecutingDirectory()
    {
        string codeBase = Assembly.GetExecutingAssembly().CodeBase;
        UriBuilder uri = new UriBuilder(codeBase);
        string path = Uri.UnescapeDataString(uri.Path);
        return Path.GetDirectoryName(path);
    }

    private static string[] GetScriptSections(string scriptText)
    {
        //split the script on "GO" commands
        string[] splitter = new string[] { "\r\nGO\r\n" };
        string[] commandTexts = scriptText.Split(splitter,
          StringSplitOptions.RemoveEmptyEntries);

        return commandTexts;
    }

    private static void RunSection(string commandText, SqlConnection con)
    {
        if (con.State == ConnectionState.Closed)
        {
            con.Open();
        }

        using (var command = new SqlCommand(commandText, con))
        {
            command.ExecuteNonQuery();
        }
    }
}