MS Access 数据库可以在调试模式下访问,但在发布时无法访问

MS Access database able to be accessed in debug mode but not accessible when published

我在 ASP.NET 中编写了一些访问 Microsoft Access 数据库的基本代码,当我 运行 在 IIS Express 上处于调试模式时,它可以工作,但是当我发布应用程序并尝试运行 在实际网站上,我得到了错误。

[IndexOutOfRangeException: There is no row at position 0.]

System.Data.RBTree`1.GetNodeByIndex(Int32 userIndex) +2430497

NIM_Tool.Default.Page_Load(Object sender, EventArgs e) +2321

System.Web.UI.Control.OnLoad(EventArgs e) +106

System.Web.UI.Control.LoadRecursive() +68

System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3785

通过修改我的一些代码,我很确定无法找到数据库,但我无法弄清楚为什么它可以在 debug/release 模式下访问,但不能从发布模式。单击发布后,所有文件都从根目录转到 bin/Release/Publish/ 文件夹,然后我将 Publish 文件夹的所有子文件夹复制到正确的服务器路径。子项 files/folder 还包含正确的 MS Access 数据库。

来自 DataLayer.cs 文件的代码

public class DataLayer { 

static OleDbConnection conn;
static OleDbCommand cmd;
static String connString;
static OleDbDataAdapter adp;

private static void CreateCommand() 
{ 
    // have also tried hardcoding this to the production server path but this failed too 
    connString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + HttpContext.Current.Server.MapPath("MyDatabase.mdb") + ";Persist Security Info=False;"
    conn = new OleDbConnection(connString);
    cmd = new OleDbCommand();
    cmd.Connection = conn;
    adp = new OleDbDataAdapter();
}

public static DataTable GetDefaultDeposit()
{
    DataTable dt = new DataTable();
    CreateCommand();
    try {
        cmd.CommandText = "SELECT * FROM Table1";
        adp.SelectCommand = cmd;
        adp.Fill(dt);
    }
    catch (Exception ex) {
    }
    return dt;
}
}

和Default.aspx.cs代码

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        DataTable dtDeposit = DataLayer.GetDefaultDeposit();
        string fixedCost = (string)dtDeposit.Rows[0]["FixedCost"];
    }
}

MyDatabase.mdb 文件与 DataLayer.cs 文件位于同一目录中。我已经尝试将数据库路径硬编码到服务器上应该访问的位置,但也得到了相同的错误消息。

一个小建议:当你发现一个错误并且不对它做任何事情时,你就是在成为你自己的敌人。它被称为 "swallowing an error",它隐藏了根本原因。

相反,我建议重新投掷。将您的(原始)异常作为 .InnerException。您可能希望在(外部)Exception 的 .Description 中包含您的 connString。 (以防万一 MapPath 没有按照您的想法去做,等等)

像这样:

public static DataTable GetDefaultDeposit()
{
    DataTable dt = new DataTable();
    CreateCommand();
    try {
        cmd.CommandText = "SELECT * FROM Table1";
        adp.SelectCommand = cmd;
        adp.Fill(dt);
    }
    catch (Exception ex) {
        throw new Exception("ConnString=" + connString, ex);
    }
    return dt;
}