DataAdapter не нужно открывать соединение с БД?

Я пытаюсь использовать DataAdapter в С#.net. и еще я что-то не понимаю про DataAdapter.

Я прочитал много статей и блогов о DataAdapter и DataReader.

Я понял, что DataAdapter автоматически открывает и закрывает базу данных, когда им это нужно.

Но,

//conn.Open();
AdsDataAdapter da;
da = new AdsDataAdapter("Select * from Test", conn);
AdsCommandBuilder cb;
cb = new AdsCommandBuilder(da);

DataSet ds = new DataSet();
da.Fill(ds, "Test");

DataRow newrow = ds.Tables["Test"].NewRow();
newrow["Name"] = "How about";
ds.Tables["Test"].Rows.Add(newrow);
da.Update(ds, "Test");

Когда я запускаю приведенный выше код, я получаю сообщение об ошибке, в котором говорится: «Соединение должно быть открыто».

Почему адаптер не может открыть соединение автоматически?

и я хочу вставить данные с помощью команды insertCommand (для этого теста я открыл соединение).

da.InsertCommand = new AdsCommand("INSERT INTO test (NAME) values('Insert Test #1')", conn);
//da.InsertCommand.ExecuteNonQuery(); // it works
da.Update(ds,"Test"); //but it does not works.

Многие примеры используют Adapter.Update(), но у меня это не работает :(

Никаких ошибок и ничего не вставлено.

и используя da.InsertCommand.ExecuteNonQuery(); вместо Update() это работает.

Что я делаю не так?

Спасибо!


person Expert wanna be    schedule 14.04.2012    source источник


Ответы (1)


MSDN говорит, что

Метод Fill неявно открывает соединение, которое использует DataAdapter, если обнаруживает, что соединение еще не открыто. Если Fill открыл соединение, он также закроет соединение после завершения Fill. Это может упростить ваш код при работе с одной операцией, такой как заполнение или обновление.

Это означает, что после da.Fill(ds, "Test"); ваше соединение закрывается самим методом. Но вам нужно открыть его для следующего обновления (и это не удается)

РЕДАКТИРОВАТЬ: псевдокод, полученный из вашего кода выше

using(AdsConnection com = new AdsConnection(connectionString));
{
    conn.Open();
    using(AdsDataAdapter da = new AdsDataAdapter("Select * from Test", conn))
    {
        AdsCommandBuilder cb = new AdsCommandBuilder(da); 
        DataSet ds = new DataSet(); 
        da.Fill(ds, "Test"); 

        // Now the connection is still open and you can issue other commands

       DataRow newrow = ds.Tables["Test"].NewRow(); 
       newrow["Name"] = "How about"; 
       ds.Tables["Test"].Rows.Add(newrow); 

       // da.Update should work here. No more connection closed.
       da.Update(ds, "Test"); 
    }
} // Exiting from the using block, the connection will be closed
person Steve    schedule 14.04.2012
comment
Открытый код подключения уже прокомментирован OP. Это должен быть комментарий. - person Pankaj; 14.04.2012
comment
@PankajGarg именно это и является причиной сбоя кода OP. Насколько я понимаю, когда вы найдете ошибку, вы опубликуете ответ. - person Steve; 14.04.2012
comment
Спасибо за ваш ответ! После заполнения DataSet соединение будет закрыто. Итак, после этого, если нам нужно обновить базу данных, нам нужно открывать и закрывать соединение вручную, верно? а про второй вопрос знаешь? - person Expert wanna be; 14.04.2012
comment
Я не знаю последовательности ваших команд. Из приведенного выше кода вы должны открыть соединение до заполнения и закрыть после. Лучше, если using утверждение. Я обновлю свой ответ некоторым псевдокодом. - person Steve; 14.04.2012
comment
также знаете ли вы, как использовать da.InsertCommand = new AdsCommand()? :) - person Expert wanna be; 14.04.2012
comment
Вам не нужно создавать InsertCommand, потому что вы создали AdsCommandBuilder, который позаботится об этом. (Однако в вашей таблице должен быть определен первичный ключ) - person Steve; 14.04.2012
comment
В тестовых таблицах есть поля ID (autoint) и Name (vchar30). Не могли бы вы показать мне, как поместить слово Hello в поле Name с помощью InserCommand, пожалуйста? Мне очень жаль, что я спросил об этом. Благодарю вас! - person Expert wanna be; 14.04.2012