Использование SqlCeConnection.Close () является зависанием приложения - PullRequest
0 голосов
/ 31 января 2012

Я занимаюсь разработкой приложения WinFrom. Я использую базу данных SDF для хранения данных. Приведенный ниже фрагмент кода для загрузки данных в сетку данных из базы данных вешает приложение. Когда я нажимаю на сетку данных, « Недопустимая попытка вызова метода Updatable при закрытии SqlResultSet » создается исключение.

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();

   }
}

Кто-нибудь, пожалуйста, посмотрите на это?

Ответы [ 3 ]

1 голос
/ 31 января 2012

Попробуйте это:

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 голосов
/ 19 февраля 2018

С помощью SQLCE вы можете открыть соединение при запуске программы и утилизировать его при закрытии программы.Это соединение может обслуживать несколько запросов без проблем.Способ SqlCeResultset задан, чтобы смотреть прямо в таблицу базы данных и не загружать какие-либо данные в память.Следовательно, когда вы закрываете свою связь, вам некуда смотреть, и поэтому он жалуется.И именно поэтому решение Brano работает, поскольку данные загружаются в память с использованием таблицы данных. В вашем случае просто откройте соединение при загрузке формы и закройте его при закрытии формы.Вам не нужно много загружать память, и я бы не советовал оба решения, представленные здесь (зачем загружать sth в память, когда он быстрее обращается к ней напрямую?).Просто.

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()
}
}
0 голосов
/ 31 января 2012

Попробуйте

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
    }
  }
}

Вы также можете проверить этот пост .Вам потребуется , чтобы сохранить соединение открытым для связывания набора данных напрямую .Вместо этого сопоставьте его с каким-то локальным объектом и свяжите это .

Надеюсь, это сработает для вас.

...