Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么对SqlCeConnection调用Open()会导致NullReferenceException?_C#_Sql Server Ce_Compact Framework_Windows Ce_Nullreferenceexception - Fatal编程技术网

C# 为什么对SqlCeConnection调用Open()会导致NullReferenceException?

C# 为什么对SqlCeConnection调用Open()会导致NullReferenceException?,c#,sql-server-ce,compact-framework,windows-ce,nullreferenceexception,C#,Sql Server Ce,Compact Framework,Windows Ce,Nullreferenceexception,我已经把这类问题转化为这个问题;瞧,这是一个更简洁、更容易理解的关于精确问题的陈述,但与更新8非常相似 基本上,mnuSendINV_Click()调用SendInventoryData(),后者调用getDataAsXMLFromTable(),后者抛出NRE 更具体地说,以下是上下文中的代码: private void mnuSendINV_Click(object sender, EventArgs e) { SendInventoryData(); } private

我已经把这类问题转化为这个问题;瞧,这是一个更简洁、更容易理解的关于精确问题的陈述,但与更新8非常相似

基本上,mnuSendINV_Click()调用SendInventoryData(),后者调用getDataAsXMLFromTable(),后者抛出NRE

更具体地说,以下是上下文中的代码:

private void mnuSendINV_Click(object sender, EventArgs e)
{
    SendInventoryData();
}    

private void SendInventoryData()
{
    String siteNum = String.Empty;
    ArrayList sbInventories = new ArrayList();
    foreach (String tbl in listboxWork.Items)
    {
        // Ignore CCR tables; just get INV tables
        if (tbl.IndexOf("CCR") >-1) continue;
        String tblName = getTableNameForInventoryName(tbl);
        siteNum = getSiteNumberFromInventoryName(tbl);
        sbInventories.Add(tblName);
    }
    foreach (string tbl in sbInventories) 
    {
        string strData = getDataAsXMLFromTable(tbl, "003"); 
        . . .
    }
}

private String getDataAsXMLFromTable(String tableName, String siteNum)
{
    string xmlOutput = String.Empty;
    // data/xml fields
    String lineId;
    String refNum;
    . . .
    String newItem;

    String paddedSiteNum = Prepad(3, siteNum);
    string connStr = String.Format("Data Source=\"\\My Documents\\HHSDB{0}.SDF\"", paddedSiteNum);
    String qry = String.Format("SELECT * FROM {0}", tableName);
    MessageBox.Show(String.Format("connstr is {0}; qry is {1}", connStr, qry));
    SqlCeConnection sqlceConn;
    SqlCeCommand sqlceCmd;
    try
    {
        sqlceConn = new SqlCeConnection(connStr);
        sqlceCmd = new SqlCeCommand(qry, sqlceConn);
        sqlceCmd.CommandType = CommandType.Text;
        MessageBox.Show("Made it just before conn.Open()"); // <= I see this
        if ((null != sqlceConn) && (!sqlceConn.State.Equals(ConnectionState.Open)))
        {
            MessageBox.Show("Will try to Open"); // <= I see this
            sqlceConn.Open(); // <= This is where the world explodes
        }
        MessageBox.Show("Made it just after conn.Open()"); // <= I don't see this/make it to here; I see the NRE instead
        SqlCeDataReader dtr = sqlceCmd.ExecuteReader(CommandBehavior.Default);
        XmlDocument doc = new XmlDocument();
        XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", null, null);
        doc.AppendChild(dec);// Create the root element
        XmlElement root = doc.CreateElement("Command");
        doc.AppendChild(root);

        try
        {
            while (dtr.Read())
            {
                // outer INV
                XmlElement invRec = doc.CreateElement("INV");

                // Line ID
                lineId = dtr["line_id"].ToString();
                XmlElement _lineId = doc.CreateElement("line_id");
                _lineId.InnerText = lineId;
                invRec.AppendChild(_lineId);

                // Ref Num
                refNum = dtr["ref_no"].ToString();
                XmlElement _refNum = doc.CreateElement("ref_no");
                _refNum.InnerText = refNum;
                invRec.AppendChild(_refNum);

                . . .

                // New Item
                newItem = dtr["new_item"].ToString();
                XmlElement _new_item = doc.CreateElement("new_item");
                _new_item.InnerText = newItem;
                invRec.AppendChild(_new_item);

                root.AppendChild(invRec);
            }
        }
        finally
        {
            xmlOutput = doc.OuterXml;
            dtr.Close();
            if (sqlceCmd.Connection.State == ConnectionState.Open)
            {
                sqlceCmd.Connection.Close();
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(String.Format("inner ex is {0}", ex.InnerException.ToString()));
        SSCS.ExceptionHandler(ex, "frmCentral.getDataAsXMLFromTable()");
    }
    return xmlOutput;
} //getDataAsXMLFromTable
INV1226006091415不存在于HHSDB003.SDF中

更新 为了回应Alexei的怀疑,以下是设备上有问题的文件:

.exe位于\Program Files\HHS中

更新2 对于聪明的新词(在异常类上似乎没有可用的“StackTrace”):

更新3 StackTrace不可用;编译失败,出现“'System.Exception'不包含'StackTrace'的定义”并出现以下错误:

更新4 我尝试了daniele3004的建议,使用以下基本代码:

private void menuItemTestSendingXML_Click(object sender, System.EventArgs e)
{
    // If one of the below works, try it with the String.Format() jazz
    //string connStr = "Data Source=\"\\My Documents\\HHSDB003.SDF"; <= NRE, without a catch block
    string connStr = @"Data Source= \\My Documents\\HHSDB003.SDF"; // NRE with a catch block IF InnerException not first checked for null
    //string connStr = @"Data Source= \\My Documents\HHSDB003.SDF";
    //string connStr = "Data Source= \\My Documents\\HHSDB003.SDF";
    //string connStr = "Data Source= \\\My Documents\\HHSDB003.SDF";

    SqlCeConnection conn = null;

    try
    {
        try
        {
            conn = new SqlCeConnection(connStr);
            conn.Open();
            MessageBox.Show("it must have opened okay");
        }
        finally
        {
            conn.Close();
        }
    }
    catch (Exception ex)
    {
        if (null == ex.InnerException)
        {
            MessageBox.Show("inner Ex is null");
        }
        MessageBox.Show(String.Format("msg is {0}", ex.Message));
    }
}
如果存在异常(而且存在,因为我到达了catch块),为什么InnerException为null

更新5 我的任何尝试都不起作用(请注意评论):

…更糟糕的是,现在它甚至不会向我显示“80004005存在文件共享冲突。另一个进程可能正在使用该文件。”err msg不再显示。相反,它变得神秘而有趣:

调用
Open()
不是问题,我认为

  • 您的
    Open()
    语句正在引发异常(可能是由于路径或密码无效或其他原因)
  • 它被catch语句捕获
  • catch语句尝试显示消息框,将InnerException作为字符串注入消息中
  • 异常
    没有
    内部异常
    ,并返回
    null
  • ToString()
    在null上调用
  • 空指针异常泄漏

堆栈跟踪将在10秒内清除此问题。

您确定
Open()
抛出NRE吗?文档没有。问题中还包括stacktrace。问题似乎在connessione的字符串中。fai是一个小型演示程序,它只执行打开和关闭连接来隔离问题。请注意:“\My Documents\HHSDB003.SDF”可能不是有效的文件路径。。。不太可能是NRE的原因,但很可疑。您没有检查处理程序中的所有对象是否为null,这可能是NRE源。一个普通的MessageBox.Show(ee.ToString())给了你什么?我不知道如何从运行.exe的手持设备上获取堆栈跟踪(不能从PC上运行它;必须将.exe复制到设备上)。StackTrace是Exception类的字符串属性。您正在使用MessageBox告诉用户您捕获的内容。。。我想你可以从那里找到答案。我会试试看,但我不太乐观;毕竟,我的“内奸是”从我的捕获块从来没有显示;为什么会显示堆栈跟踪?我发现没有StackTrace可用(参见更新2)。不要相信Intellisense,看看API。每个异常都有一个StackTrace属性。至于为什么堆栈跟踪会显示而InnerException不会显示,这是因为MessageBox.Show调用实际上失败了。。。您在尝试打印InnerException时遇到异常。您已经解决了这个问题。正如我所说的。。。InnerException为空(基于您的更新)。忘了追踪吧。您已发现空指针异常源。“如果存在异常(确实存在,因为我到达了catch块),为什么InnerException为null?”因为没有异常!当使用异常包装另一个异常(装饰器模式)时,将使用InnerException。Exception中没有消息,所以我猜您只能继续使用异常的类型。
private void menuItemTestSendingXML_Click(object sender, System.EventArgs e)
{
    // If one of the below works, try it with the String.Format() jazz
    //string connStr = "Data Source=\"\\My Documents\\HHSDB003.SDF"; <= NRE, without a catch block
    string connStr = @"Data Source= \\My Documents\\HHSDB003.SDF"; // NRE with a catch block IF InnerException not first checked for null
    //string connStr = @"Data Source= \\My Documents\HHSDB003.SDF";
    //string connStr = "Data Source= \\My Documents\\HHSDB003.SDF";
    //string connStr = "Data Source= \\\My Documents\\HHSDB003.SDF";

    SqlCeConnection conn = null;

    try
    {
        try
        {
            conn = new SqlCeConnection(connStr);
            conn.Open();
            MessageBox.Show("it must have opened okay");
        }
        finally
        {
            conn.Close();
        }
    }
    catch (Exception ex)
    {
        if (null == ex.InnerException)
        {
            MessageBox.Show("inner Ex is null");
        }
        MessageBox.Show(String.Format("msg is {0}", ex.Message));
    }
}
"InnerEx is null"
"msg is " // [ex.Message is blank]
//string connStr = "Data Source=\"\\My Documents\\HHSDB003.SDF"; <= NRE
//string connStr = @"Data Source= \\My Documents\\HHSDB003.SDF"; // No NRE, but exception
//string connStr = @"Data Source= \\My Documents\HHSDB003.SDF"; // "inner ex is null; msg is [blank]
//string connStr = "Data Source= \\My Documents\\HHSDB003.SDF"; // ""
//string connStr = "Data Source= \\\My Documents\\HHSDB003.SDF"; <= won't even compile ("unrecognized escape sequence")
//string connStr = @"Data Source= My Documents\HHSDB003.SDF"; // "inner ex is null; msg is [blank]
//string connStr = "Data Source= My Documents\HHSDB003.SDF"; <= won't even compile ("unrecognized escape sequence")
string connStr = "Data Source= My Documents\\HHSDB003.SDF"; // "inner ex is null; msg is [blank]
SqlCeConnection conn = new SqlCeConnection(@"Data Source=/My Documents/HHSDB003.sdf;");
try
{
    conn.Open();
    MessageBox.Show("Connection!");
}
catch (SqlCeException ee)  // <- Notice the use of SqlCeException to read your errors
{
    SqlCeErrorCollection errorCollection = ee.Errors;

    StringBuilder bld = new StringBuilder();
    Exception inner = ee.InnerException;

    if (null != inner) 
    {
        MessageBox.Show("Inner Exception: " + inner.ToString());
    }
    // Enumerate the errors to a message box.
    foreach (SqlCeError err in errorCollection) 
    {
        bld.Append("\n Error Code: " + err.HResult.ToString("X")); 
        bld.Append("\n Message   : " + err.Message);
        bld.Append("\n Minor Err.: " + err.NativeError);
        bld.Append("\n Source    : " + err.Source);

        // Enumerate each numeric parameter for the error.
        foreach (int numPar in err.NumericErrorParameters) 
        {
            if (0 != numPar) bld.Append("\n Num. Par. : " + numPar);
        }

        // Enumerate each string parameter for the error.
        foreach (string errPar in err.ErrorParameters) 
        {
            if (String.Empty != errPar) bld.Append("\n Err. Par. : " + errPar);
        }

    }
    MessageBox.Show(bld.ToString());
    bld.Remove(0, bld.Length);
}
@"Data Source=\My Documents\HHSDB003.sdf; File Mode=Read Write;");