Проблема с несколькими SqlDataReader и SqlCommand в классе

У меня проблема с С#, у меня есть класс с функцией для SqlDataReader и другой для SqlCommand (первый предназначен только для чтения значений из базы данных, а второй - для INSERT, UPDATE, DELETE... в той же БД ).

Проблема в том, что для первой части кода (логин) мне нужно искать значения в Active Directory (это работает), затем я должен посмотреть, есть ли у пользователя имя пользователя и пароль в моей собственной БД (это работает) , а затем, если пользователя нет в БД, мне нужно создать его и получить идентификатор, если он уже создан, мне просто нужно получить идентификатор.

Проблема в том, что я получаю это сообщение:

InvalidOperationException не было обработано пользовательским кодом

Уже существует Open DataReader, связанный с этой командой, который должен быть закрыт первым.

Есть код:

Class.cs:

    private static string MyConnectionString = "THIS IS MY CONNECTION";
    private SqlConnection MyConnection = new SqlConnection(MyConnectionString);
    public SqlCommand MyCommand = new SqlCommand();
    public SqlDataReader MyReader = null;

    public void DBMyReader(String SqlQuery)
    {
        if (MyConnection.State != ConnectionState.Open)
            MyConnection.Open();

        MyCommand.Connection = MyConnection;
        MyCommand.CommandText = SqlQuery;
        MyReader = MyCommand.ExecuteReader(CommandBehavior.CloseConnection);
    }

    public void DBMyUpdate(String SqlQuery)
    {
        if (MyConnection.State != ConnectionState.Open)
            MyConnection.Open();

        var cmdTest = new SqlCommand();

        cmdTest.Connection = MyConnection;
        cmdTest.CommandText = SqlQuery;
        cmdTest.ExecuteNonQuery();
    }

    public void DBMyInsert(String SqlQuery)
    {
        DBMyUpdate(SqlQuery);
    }

** Логин.aspx.cs: **

                    MyClass.DBMyReader("SELECT util_codi,util_logi,util_nome FROM Tgep_util WHERE util_logi='"
                            + Session["username"].ToString() + "'");
            MyClass.MyReader.Read();

            if (!MyClass.MyReader.HasRows)
            {
                MyClass.MyReader.Close();
                MyClass.DBMyInsert("INSERT INTO Tgep_util(util_logi,util_nome) "
                            + "VALUES ('" + Session["username"].ToString() + "','" + Session["nome"].ToString() + "')");
            }

            MyClass.DBMyReader("SELECT util_codi,util_logi,util_nome FROM Tgep_util WHERE util_logi='"
            + Session["username"].ToString() + "'");

            MyClass.MyReader.Read();

            Session["user_id"] = MyClass.MyReader["util_codi"].ToString();

            Response.Redirect("FRM_Principal.aspx");

Изменить: обновить код (пока работает)


person aliasbody    schedule 09.06.2011    source источник


Ответы (2)


Ошибка означает именно то, что она говорит. Вы загрузили SQLCommand и начали читать строки, а теперь пытаетесь выполнить вставку. Сначала вам нужно закрыть этот считыватель или использовать новую команду.

в функции DBMyUpdate вы можете просто создать новую команду:

public void DBMyUpdate(String SqlQuery)
{
    if (MyConnection.State != ConnectionState.Open)
        MyConnection.Open();
    var cmdUpdate = new SqlCommand();

    cmdUpdate.Connection = MyConnection;
    cmdUpdate.CommandText = SqlQuery;
    cmdUpdate.ExecuteNonQuery(CommandBehavior.CloseConnection);
}

редактировать: на основе комментариев к этому ответу требуется использовать отдельные соединения, что кажется странным/неправильным.

person Fosco    schedule 09.06.2011
comment
Привет, спасибо за вашу помощь. Проблема в том, что если я закрою Reader, мне придется начать еще раз с запроса, я не знаю, очень ли он эффективен... Есть ли решение, позволяющее решить проблему только с помощью класса? - person aliasbody; 09.06.2011
comment
@aliasbody Я только что добавил способ изменить вашу функцию DBMyUpdate, чтобы использовать новую команду, которая не должна конфликтовать с вашей существующей программой чтения. - person Fosco; 09.06.2011
comment
Не беспокойтесь об эффективности, пока ваш код не заработает. Вам не нужен быстрый сломанный код. - person John Saunders; 09.06.2011
comment
С вашим кодом я получил ту же ошибку... Это не имеет никакого смысла, так как я использую новую SqlCommand... - person aliasbody; 09.06.2011
comment
@aliasbody, вы уверены, что это было перекомпилировано? просто убедиться, потому что это не звучит правильно, чтобы получить ту же ошибку. - person Fosco; 09.06.2011
comment
Я уже перекомпилировал проект (Build, Clean, Rebuild и т. д.) и та же ошибка... Что-то делать с соединением? - person aliasbody; 09.06.2011
comment
@aliasbody говорит вам, на какой строке # происходит сбой исключения? Мы уверены, что это функция обновления? Вы можете попробовать новое подключение, но не как окончательное решение, а просто для устранения неполадок... - person Fosco; 09.06.2011
comment
Привет еще раз (ps: спасибо за всю вашу помощь), строка, на которую падает исключение, - это MyCommand.ExecuteNonQuery(); на DBMyUpdate, когда вставка сделана в файле входа. Я уже пытался создать 2 разные переменные SqlCommand, одну для обновления, а другую для вставки, и возникает та же ошибка. - person aliasbody; 09.06.2011
comment
@aliasbody хорошо .. вы пытались использовать уникальное соединение для функции вставки? - person Fosco; 09.06.2011
comment
Это работает, но только для добавления пользователя, потому что, когда я попытался во второй раз войти (и создать), удалить пользователя, я получаю ту же ошибку в MyDbReader - person aliasbody; 09.06.2011
comment
@aliasbody Похоже, что с созданным вами уровнем доступа к данным возникла более серьезная проблема, которая выходит за рамки этого вопроса. - person Fosco; 09.06.2011
comment
Но я действительно не понимаю, почему, у меня есть только 1 соединение, я делаю чтение и затем вставляю, чем пытаюсь прочитать уже открытый DataReader и получить значения... - person aliasbody; 09.06.2011
comment
PS: есть ли вероятность, что проблема возникает из-за статического соединения? - person aliasbody; 09.06.2011
comment
Я решил проблему, удалив статику и изменив код ... Я не знаю, как это повлияет на какой-либо другой код программы, но только время и тесты могут сказать мне ... (Я обновлю код на пост... очень не хочется повторять DbRead но думаю это единственное решение) - person aliasbody; 09.06.2011

Вы не можете использовать тот же DataReader для insert/update, который вы использовали для вставки. Вы должны сначала закрыть DataReader, прежде чем связать какую-либо другую команду с DataReader.

person FIre Panda    schedule 09.06.2011
comment
Но когда я попытался закрыть Reader в классе (чтобы действие было автоматическим), я получил сообщение об ошибке, говорящее, что в функции обновления нет открытия соединения: S... - person aliasbody; 09.06.2011