2014-06-13 276 views
0

我想从数据库中检索数据。我添加了一个.sdf文件,并编写了下面显示的代码。我的表名是info,它有三列:id,namecode不能填充CheckedListBox

我想要做的是用这些数据填充CheckedListBox,但是当我执行我的代码时没有任何反应。 CheckedListBox是空的。我究竟做错了什么?

SqlCeDataReader dr; 
SqlCeConnection con; 
SqlCeCommand cmd; 

void loadData() 
{ 
    cmd.CommandText = "select column_name from Information_schema.columns where table_name='info' order by ordinal_position"; 
    con.Open(); 
    dr = cmd.ExecuteReader(); 

    if (dr.HasRows) 
    { 
     while (dr.Read()) { 
     checkedListBox1.Items.Add(dr[0].ToString()); 
    } 

    dr.Close(); 
    con.Close(); 
} 

private void Form1_Load(object sender, EventArgs e) 
{ 
    con = new SqlCeConnection(); 
    [email protected]"Data Source=c:\users\xxx\documents\visual studio 2012\Projects\WindowsFormsApplication1\WindowsFormsApplication1\Database1.sdf"; 
    cmd = new SqlCeCommand(); 
    cmd.Connection = con; 
    loadData(); 
} 
+1

只是指出,你有很多应该在'使用'语句中的可支配资源。有关更多信息,请参阅http://stackoverflow.com/q/212198/。 – Anthony

+2

今天将是使用调试器的好日子。 – LarsTech

+1

您是否尝试调试它并检查“dr.HasRows”是否为真?!? – Leonardo

回答

0

你基本上是要求你的代码段进行调试。由于几个原因,这很棘手。首先你的代码调用一个数据库,然后做一个奇怪的查询,它从系统数据库获取列信息,而不是从你自己的表中获取信息。这里没有人确切知道结果会是什么。有可能用其他具有类似效果的行代替它(例如,在代码中使用一些虚拟值初始化的列表),但通过这样做,我们可以改变行为,以便错误消失,并且我们会不要聪明。我们会在一分钟后回到这个想法。

像这样的问题对于StackOverflow并不理想。其中一个原因就是我刚刚提到的 - 为了帮助你,你可能很难复制你的代码。因此你可能得不到有用的答案。另一个稍微相反的原因是,有人(比我稍微勤奋和谨慎)可能会在代码中发现一个简单的错字或陷阱。这可能已经发生,而我输入这个。他们会发布一个答案或评论指出这一点,并且你会修正你的代码。但是,这个问题对其他人来说并不是特别有用。没有人会像你一样犯同样的错字或错误。即使他们这样做,它可能会略有不同,与CheckedListBoxSqlCeDataReader无关,他们将永远不会发现这个问题。

这些类型的问题和答案本质上并没有增加任何内容。他们也不会对你特别有用,这就是为什么:你不会学习调试。

根据我的经验,优秀的程序员几乎总是很好的调试器。我们大多数人犯了很多小错误 - 发现并修复这些错误是平均生产力和高生产率之间的差异。作为一个好的调试器也意味着你与你的想法和你的(或别人的)代码有不同的关系。您可以更灵活地思考,同时在您的脑海中持有许多不同的案例和可能性。这被称为发散思维,并正在慢慢被认为是一样重要的收敛思考,思考导致一个答案。

你应该如何处理你的问题,并作为一名程序员,正确调试。如果你这样做了,仍然面临一个困难的问题(或者你的工具中可能存在一个bug),那么你可以用一个更短的代码片段来发布,并且能够更好地描述非预期的行为。

基本上有两种调试代码的方法 - 逐步执行代码和“打印行”。 (像内核代码,多线程和消息传递之类的奇怪和困难的代码可能更难以调试 - 这两种技术将为您带来很多其他方面的帮助。)两者的主要想法是您查看变量的中间值,在评估的不同阶段。调试支持在Visual Studio中逐步执行C#代码非常好,但为了使事情简单且合理,语言无关,我将使用打印行作为示例。

只需在程序中的任意位置添加一行,您想知道执行流程是否到达那里。例如

Console.WriteLine("We do have some rows"); 

应该去后if (dr.HasRows) {线。如果这是一个控制台程序并运行它,则会在控制台窗口中看到(或不)该输出。否则,您可以使用Debug.Print将文本发送到VS的“输出”窗口,或者使用Winforms MessageBox在警报窗口中显示文本。

如果您的查询结果中有任何行,您将会看到直通车。如果没有,您的查询或执行方式会有问题。您应该首先以不同的方式在同一个数据库上运行相同的查询,例如sqlcmd或Sql Server Management Studio。事实上,你没有这样做,并且你不知道如果dr.HasRows是真实的,立即向我表明你没有正确调试。 [编辑:@Leonardo也在评论中精确地指出了同样的事情。]如果在其他地方运行查询时得到一些有效的响应行,但在运行此代码时没有,那么设置连接或运行在C#中查询。如果您没有获取任何行,则查询本身存在问题。直接尝试不同的查询,直到找到正确的查询,然后将其放回到C#代码中。 (第三种可能性是'没有行'是正确的回应,并且您的代码应该知道如何正确处理这种情况。)

假设另一方面dr.HasRows为真。 dr.Read或与添加到复选框有一些问题。要消除前者,请尝试在内部循环中使用printline。这次输出你感兴趣的值:

Debug.Print("Value to be added is: " + dr[0].ToString()); 

你会很快看到这些看起来是否合理。如果他们这样做,试着找出checkListBox1出了什么问题。在循环的每次迭代后打印checklistBox1和/或checkListBox1.Items的值。尝试写一些不同的值,可能是一个字符串常量或一个硬编码的字符串列表来代替Items,看它是否有效。确保checkListBox1实际上是空的,并且在访问它之前确实调用了代码来填充它。

干得好,您刚刚了解到两种主要调试方法之一的主要两部分。您可以识别代码是如何循环和分支(通过把信息打印线)

Console.WriteLine("Got this far!"); 

,你可以找到你的数据的价值是(通过打印变量的实际值)

Console.WriteLine("x is currently equal to " + x.ToString()); 

关于printlines的好处是,无论何时您控制某种输出或日志记录,都可以在没有任何其他工具的情况下进行调试。

现在您要测试代码的每一步,观察传递给它的数据并从中返回。试着准确找出哪些部件按预期工作,哪些部件已经使用了上一步传递给他们的不良信息。任何你不清楚的地方(比如数据库访问),你都会尝试以不同的方式重新运行,以便在代码中使用它。例如,编写一个双线程序,创建并显示一个ListCheckBox,以确保您知道如何操作。

如果你正在使用一些极其实验性的工具,你最终可能会发现一个错误,并且你自己的代码很好。使用经过其他人广泛尝试和测试的技术,这是非常不可能的。最可能的结果是,你发现你的(可能很简单)错误并修复它。除此之外,您可以使用小得多的测试用例返回到StackOverflow,询问关于使用组件的方式或某些难以理解的简单查询的非显而易见的内容。 (Winforms和SQL Server都包含许多问题,这会产生很好的问题来帮助其他人。)当您这样做时,您将能够共享调试结果,让回答者准确知道代码似乎不在哪里按预期行事。如果你确实有这样的问题,你也可能会搜索并发现其他人已经遇到过并且已经回答了。

不要忘了,一旦你完成调试,你可以把你的工作代码http://codereview.stackexchange.com,以获取有关使它更短,更优雅,更高效和更防错的意见。祝你好运!

0

请尽量使用命令文本如下:

cmd.ComandText = "Select * from infor".