2012-01-31 93 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() 
} 
}