2012-01-31 112 views
0

我正在开发一个WinFrom应用程序。我正在使用SDF数据库来存储数据。 下面的代码片段将数据从DataBase加载到datagrid挂起了应用程序。当我点击数据网格时, “无效尝试调用方法当SqlResultSet关闭时可更新”正在抛出异常。使用SqlCeConnection.Close()挂起应用程序

public partial class Form1 : Form 
{ 
    private SqlCeConnection _conn; 

    public Form1() 
    { 
     InitializeComponent(); 
     _conn = new SqlCeConnection(@"Data Source = |DataDirectory|\Database1.sdf"); 
     this.dataGridView1.AutoGenerateColumns = true; 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     SqlCeCommand sqlcmd = new SqlCeCommand(); 
     sqlcmd.Connection = _conn; 
     sqlcmd.CommandText = "SELECT ID, UserName FROM Table1"; 
     _conn.Open(); 

     SqlCeResultSet rs = sqlcmd.ExecuteResultSet(ResultSetOptions.Scrollable); 
     this.bindingSource1.DataSource = rs; 
     _conn.Close(); 

    } 
} 

任何人都可以请看看它吗?

+0

如果我评论_conn.Close(),它正在工作,并且数据网格正在加载数据。 – mlg 2012-01-31 10:35:17

+0

你可以试试[SqlCeCommand.ExecuteReader](http://msdn.microsoft.com/en-us/library/0c9att46(v = vs.85).aspx)? – 2012-01-31 10:50:06

+0

嗨阿马尔,ExecuteReader正在工作。非常感谢.ExecuteReader或SqlCeResultSet对于大量记录更快?我认为SqlCeResultSet更快。不过不确定。 – mlg 2012-01-31 11:07:07

回答

0

试试这个

public partial class Form1 : Form 
{ 
    private SqlCeConnection _conn; 

    public Form1() 
    { 
    InitializeComponent(); 
    this.dataGridView1.AutoGenerateColumns = true; 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
    SqlCeDataReader rdr = null; 
    try 
    { 
     using(SqlCeConnection conn = new SqlCeConnection(@"Data Source = |DataDirectory|\Database1.sdf")) 
     { 
      conn.Open(); 

      SqlCeCommand sqlcmd = new SqlCeCommand("SELECT ID, UserName FROM Table1", conn); 
      sqlcmd.Connection.Open(); 

      rdr = sqlcmd.ExecuteReader(); 

      //Custom Object is object with same structure as your data table 
      List<CustomObject> dataSource = new List<CustomObject>(); 
      while (rdr.Read()) 
      { 
       var customObject = new CustomObject(); 
       customObject.Id = rdr.GetInt32(0); 
       //so on 

       dataSource.Add(customObject); 
      } 

      this.bindingSource1.DataSource = dataSource; 
      rdr.Close(); 
     } 
    } 
    catch(Exception ex) 
    { 
     //Handle Exception 
    } 
    } 
} 

您可以检查this post了。您将需要直接打开绑定数据集的连接。而不是这样做将其映射到某个本地对象并绑定该

希望这对你有用。

+0

一堆谢谢阿马尔。这是行得通的。并感谢您的链接。 – mlg 2012-01-31 12:00:23

+0

我修改了一下代码。 (rdr.Read())前分配rdr = rs { – mlg 2012-01-31 14:39:59

1

试试这个:

public partial class Form1 : Form 
{ 

    public Form1() 
    { 
     InitializeComponent(); 
     this.dataGridView1.AutoGenerateColumns = true; 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     using(SqlCeConnection _conn = new SqlCeConnection(@"Data Source = |DataDirectory|\Database1.sdf")){ 
      _conn.Open(); 
      SqlCeCommand sqlcmd = _conn.CreateCommand(); 
      sqlcmd.CommandText = "SELECT ID, UserName FROM Table1"; 

      SqlCeDataAdapter a = new SqlCeDataAdapter(); 
      a.SelectCommand = sqlcmd; 
      DataTable t = new DataTable(); 
      a.Fill(t); 

      this.bindingSource1.DataSource = t; 
     } 

    } 


} 
+0

“使用”状态会为您关闭它。 – brano 2012-01-31 11:03:31

+0

我已经试过这个。但挂.. – mlg 2012-01-31 11:05:49

+0

它是否像以前一样悬挂应用程序?挂起何时发生?当Form1加载? – brano 2012-01-31 11:12:31

0

使用SQLCE,您可以在程序启动时打开连接,并在程序关闭时处理它。该连接可以毫无问题地服务于多个请求。 SqlCeResultset的构思方式是直接查看数据库表,而不是将任何数据加载到内存中。因此,当你关闭连接时,无处可看,这就是它抱怨的原因。这就是为什么使用分支解决方案工作的原因,因为使用数据表将数据加载到内存中。在您的情况下,只需在表单加载中打开一个连接并在表单关闭时关闭它。你不需要做大量的内存加载,我不会推荐这里介绍的两种解决方案(为什么在内存中加载它直接访问它的速度更快?)。简单。

public partial class Form1 : Form 
{ 
    private SqlCeConnection _conn; 

    public Form1() 
    { 
     InitializeComponent(); 
     _conn = new SqlCeConnection(@"Data Source = |DataDirectory|\Database1.sdf"); 
     this.dataGridView1.AutoGenerateColumns = true; 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     SqlCeCommand sqlcmd = new SqlCeCommand(); 
     sqlcmd.Connection = _conn; 
     sqlcmd.CommandText = "SELECT ID, UserName FROM Table1"; 
     _conn.Open(); 

     SqlCeResultSet rs = sqlcmd.ExecuteResultSet(ResultSetOptions.Scrollable); 
     this.bindingSource1.DataSource = rs; 
//dont close the connection 
     // _conn.Close(); 

    } 

protected override Close() 
{ 
if (_conn != null) 
_conn.close(); 
base.Close() 
} 
}