Mam problem z C#, mam Klasę z funkcją dla SqlDataReader i drugą dla SqlCommand (pierwsza jest tylko do odczytu wartości z bazy danych, a druga dla INSERT, UPDATE, DELETE... w tej samej DB ).

Problem polega na tym, że dla pierwszej części kodu (login) muszę wyszukać wartości z Active Directory (działa), a następnie muszę sprawdzić, czy użytkownik ma nazwę użytkownika i hasło we własnej bazie danych (działa) , a następnie, jeśli użytkownika nie ma w bazie danych, to muszę go utworzyć i uzyskać identyfikator, jeśli już jest utworzony, po prostu muszę uzyskać identyfikator.

Problem polega na tym, że otrzymuję tę wiadomość:

InvalidOperationException został nieobsługiwany przez kod użytkownika

Istnieje już Open DataReader powiązany z tym poleceniem, który ma zostać zamknięty jako pierwszy.

Jest kod:

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

** Login.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");

Edycja : Aktualizuj kod (działa na razie)

0
aliasbody 9 czerwiec 2011, 19:37

2 odpowiedzi

Najlepsza odpowiedź

Błąd oznacza dokładnie to, co mówi. Załadowałeś SQLCommand i zacząłeś czytać wiersze, a teraz próbujesz wstawić. Musisz najpierw zamknąć ten czytnik lub użyć nowego polecenia.

W funkcji DBMyUpdate możesz po prostu utworzyć nowe polecenie:

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

Edit: na podstawie komentarzy do tej odpowiedzi, wymagało to użycia oddzielnych połączeń, co wydaje się dziwne/niepoprawne.

3
Fosco 9 czerwiec 2011, 20:13
Cześć, dziękuję za pomoc. Problem polega na tym, że jeśli zamknę Reader, to muszę ponownie uruchomić zapytanie, nie wiem, czy jest to bardzo wydajne... Czy istnieje rozwiązanie problemu tylko przy użyciu classe ?
 – 
aliasbody
9 czerwiec 2011, 19:44
Właśnie dodałem sposób na zmianę funkcji DBMyUpdate, aby używała nowego polecenia, które nie powinno kolidować z istniejącym czytnikiem.
 – 
Fosco
9 czerwiec 2011, 19:45
Nie martw się o wydajność, dopóki Twój kod nie zadziała. Nie chcesz szybkiego złamanego kodu.
 – 
John Saunders
9 czerwiec 2011, 19:46
Z twoim kodem dostałem ten sam błąd... To nie ma sensu, ponieważ używam nowego SqlCommand...
 – 
aliasbody
9 czerwiec 2011, 19:49
Czy jesteś pewien, że to zostało przekompilowane? po prostu upewniam się, ponieważ to nie brzmi dobrze, aby uzyskać ten sam błąd..
 – 
Fosco
9 czerwiec 2011, 19:51

Nie możesz użyć tego samego DataReader dla insert/update, którego użyłeś do wstawienia. Musisz najpierw zamknąć DataReader, zanim powiążesz inne polecenie z DataReader.

0
FIre Panda 9 czerwiec 2011, 19:44
Ale gdy próbowałem zamknąć Readera w klasie (a więc akcja jest automatyczna) to dostałem błąd mówiący, że nie ma połączenia Open przy funkcji Update :S...
 – 
aliasbody
9 czerwiec 2011, 19:51