proste logowanie do aplikacji

0

Witam!

Potrzebuję stworzyć proste logowanie do aplikacji w Windows Forms.

Login i hasło są zapisane w bazie danych jawnym tekstem w jednej tabeli Uzytkownicy.

Co tego celu stworzyłem formatke, któa uruchamia się jako pierwsza, i żąda wpisania loginu i hasła (TextBox dla loginu, i MaskedTextBox dla hasła), oraz przycisk Zaloguj, którego kod wygląda tak:

private void buttonZaloguj_Click(object sender, EventArgs e)
        {
            proceduryBudSystem.wyszukajDaneLogowania(textBoxLogin.Text, maskedTextBoxHaslo.Text);
            wyszukajDaneLogowaniaResult weryfikacja = new wyszukajDaneLogowaniaResult();

            if (textBoxLogin.Text == weryfikacja.login)
            {
                Application.Run(new FormGlowne());
                if (maskedTextBoxHaslo.Text == weryfikacja.haslo) MessageBox.Show("Logowanie zakończone sukcesem!");
            }
            else
            {
                MessageBox.Show("Niepoprawny login i/lub hasło!");
                maskedTextBoxHaslo.ResetText();
                textBoxLogin.ResetText();
            }
        }

Natomiast, procedura wyszukująca dane logowania w bazie wygląda tak:

CREATE PROCEDURE dbo.wyszukajDaneLogowania
	@loginUzytkownika text,
	@hasloUzytkownika text
AS
	SELECT login, haslo FROM Uzytkownicy WHERE login LIKE @loginUzytkownika AND haslo LIKE @hasloUzytkownika
	RETURN

Byłbym bardzo wdzięczny, gdyby ktoś napisał co robie źle, bo problem polega na tym że ciągle wywala mi komunikat "Niepoprawny login i/lub hasło!" mimo wpisywania dobrego loginu oraz hasła :)

0

sprawdź co ci wyświetla samo:

 
SELECT login, haslo FROM Uzytkownicy WHERE login LIKE @loginUzytkownika AND haslo LIKE @hasloUzytkownika

( gdzie @login i @Hasło ustaw na sztywno)

0

SQL:

  1. Nie like, tylko porównanie za pomocą operatora porównania (=).
  2. Nie zwracaj hasła. Login, jakieś Id, imię użytkownika etc. to ma sens. Albo w ogóle zwracaj wartość true/false (1/0).
  3. login i hasło raczej nie powinny być typu text, a lepiej nvarchar (n - unicode).

C#:

  1. MessageBox o udanym logowaniu raczej pokaż przed formą główną.
  2. Dziwnie wygląda odpalenie procedury:
    proceduryBudSystem.wyszukajDaneLogowania(textBoxLogin.Text, maskedTextBoxHaslo.Text);
    wyszukajDaneLogowaniaResult weryfikacja = new wyszukajDaneLogowaniaResult();
    Nie wnikam do końca w ten pomysł, ale lepiej żeby weryfikacja posiadała pole bool CzyZweryfikowany i w warunku sprawdzaj to. A jeśli już chcesz porównywać stringi to zastanów się czy wielkość literm ma znaczenie. Tak jak to zrobiłeś ma, wieć jan a Jan to dla ciebie inny login. Pamiętaj że na bazie to porównania może być CI (case insensitive), a domyślne collation w ms sql server jest latin1 CI. Ta sama uwaga do hasła, tu już z kolei wielkość liter ma znaczenie.
0

maszynaz po wpisaniu na sztywno zwraca to co jest wpisane po SELECT, chyba ze rekordu o który pytam nie ma w bazie, to wtedy nic nie zwraca, tak że tu nie widze problemu

massther nie ma sensu teraz zmieniać typu danych dla loginu i hasła z text na nvchar, bo musiał bym na nowo generować modele Linq to SQL, DataSet itp. itd, a aplikacja jest już prawie ukończona, i nie wykluczone że caałkowicie sie mi to może wysypać, co już niestety miało miejsce, w efekcie tez nie moge zmienić LIKE na symbol porównania "=" bo on nie działa dla typu danych text, niestety.

Jesli chodzi o porównywanie string'ów przy logowaniu, to mam na celu właśnie rozróżnianie wielkich i małych liter zarówno w loginie jak i haśle dlatego tak to zrobiłem i wydaje się to najlepszym rozwiązaniem, tym bardziej że docelowo w aplikacji dojdzie jeszcze kwestia nadawania uprawnień poszczególnym grupom użytkowników, chyba że istnieje jakieś lepsze wyjscie logowania i nadawania grupom użytkowników odpowiednich praw?

Zmodyfikowałem trochę kod, według Twoich wskazówek:
kod C#:

private void buttonZaloguj_Click(object sender, EventArgs e)
        {
            proceduryBudSystem.wyszukajDaneLogowania(textBoxLogin.Text, maskedTextBoxHaslo.Text);
            wyszukajDaneLogowaniaResult weryfikacja = new wyszukajDaneLogowaniaResult();

            if (textBoxLogin.Text == weryfikacja.login)
            {
                if (maskedTextBoxHaslo.Text == weryfikacja.haslo) MessageBox.Show("Logowanie zakończone sukcesem!");
                Application.Run(new FormGlowne());
            }
            else
            {
                MessageBox.Show("Niepoprawny login i/lub hasło!");
                maskedTextBoxHaslo.ResetText();
                textBoxLogin.ResetText();
            }
        }

kod SQL:

ALTER PROCEDURE dbo.wyszukajDaneLogowania
	@loginUzytkownika text,
	@hasloUzytkownika text
AS
	SELECT login FROM Uzytkownicy WHERE login LIKE @loginUzytkownika AND haslo LIKE @hasloUzytkownika
	RETURN

W dalszym ciągu, jednak wywala ten sam błąd.

0

Jeśli upierasz się przy zostawieniu text i like to twoja sprawa. O ile jest to projekt studencki to olej moje czepianie się, ale jeśli nie to za takie głupoty karałbym chłostą.
Wiesz że VS (jak i inne IDE) mają super opcje debug'owania. Odpal to w debugu i przechodź krok po kroku i zobacz co ci zwraca w obiekcie weryfikacja, zobacz na którym porównaniu nie przechodzi i czemu.
Jakoś wcześniej przeoczyłem tego drugiego if przez MessageBox - co to w ogóle jest??? o_O
To ma sens:

 if (textBoxLogin.Text == weryfikacja.login && maskedTextBoxHaslo.Text == weryfikacja.haslo)
            {
                MessageBox.Show("Logowanie zakończone sukcesem!");
                Application.Run(new FormGlowne());
            }
            else
            {
                MessageBox.Show("Niepoprawny login i/lub hasło!");
                maskedTextBoxHaslo.ResetText();
                textBoxLogin.ResetText();
            }

ale twoje nie ma sensu!

0

A po co w ogóle robić logowanie, skoro hasło jest jawnym tekstem?

0

massther po prostu wydawało mi się że będzie duzo roboty ze zmianami typu z text na nvarchar, ale myliłem się, przynaje i zmieniłem już to tak jak być powinno. W dalszym ciągu, natomiast nie mogę uzyć "=" do porównania, gdyż VS wyświetla komunikat że jest to niepoprawne porównanie dla typów text i nvarchar i czepia się złego nazwania kolumny login i hasło.

W obiekcie weryfikacja nie wiedzieć czemu cały czas jest NULL, aczkolwiek jak wywołam samą procedure, i wpisze login i hasło na sztywno to działa ona dobrze tzn. zwraca dane z tego rekordu, który mnie w danej chwili interesuje.

W tej chwili kod wygląda tak,

kod C#:

private void buttonZaloguj_Click(object sender, EventArgs e)
        {
            proceduryBudSystem.wyszukajDaneLogowania(textBoxLogin.Text, maskedTextBoxHaslo.Text);
            wyszukajDaneLogowaniaResult weryfikacja = new wyszukajDaneLogowaniaResult();

            if (textBoxLogin.Text == weryfikacja.login && maskedTextBoxHaslo.Text == weryfikacja.haslo)
            {
                MessageBox.Show("Logowanie zakończone sukcesem!");
                Application.Run(new FormGlowne());
            }
            else
            {
                MessageBox.Show("Niepoprawny login i/lub hasło!");
                maskedTextBoxHaslo.ResetText();
                textBoxLogin.ResetText();
            }
        }

kod SQL:

ALTER PROCEDURE dbo.wyszukajDaneLogowania
	@loginUzytkownika nvarchar(50),
	@hasloUzytkownika nvarchar(50)
AS
	SELECT login, haslo FROM Uzytkownicy WHERE login = @loginUzytkownika AND haslo = @hasloUzytkownika
	RETURN 1

...i dalej to samo

0

A po co ci ten return w tej procedurze sql? Jakoś go przeoczyłem, za msdn: "Unless documented otherwise, all system stored procedures return a value of 0. This indicates success and a nonzero value indicates failure.", stawiam że jakieś mechanizmy linq2sql bazując na wartości zwróconej przez return wnioskują że procedura wykonała się niepoprawnie i nie dotykają result set.
Jeśli używasz linq2sql to po co ci procedury? Nie że nie można ale po to używa się OR mappera, żeby wywalić logikę z bazy, a procedury zazwyczaj zawierają właśnie taką logikę.
Nvarchar powinny być kolumny w tabeli oraz parametry w procedurze.

0

Nvarchar jak zmieniłem, to wszędzie, zarówno jako typ kolumny jak i typ parametru procedury.

Jesli chodzi o RETURN to omyłkowo pozostał po próbie weryfikacji za pomocą zmiennej bool o której była mowa na początku, ale tu znowu logowanie zawsze było zakończone sukcesem bo zmienna bool zawsze miała true. W dalszym ciągu obiekt weryfikacja zawiera null, a skąd to sie bierze to ja juz nie wiem.

hmm... dziwna sprawa, po uruchomieniu samej procedury z wpisanymi na sztywno danymi, procedura ta wyświetla tylko pierwszą z pytanych kolumn danego rekordu, nawet po wpisaniu SELECT * FROM... wyświetla sie tylko kolumna id i pasujący rekord, natomiast w SQL Management Studio ta sama procedura działa normalnie.

0

Zobacz jak masz diagram linq2sql. Może w nim masz błędy.

0

własnie nie widze błędów w tym diagramie :/

próbuje to teraz zrobić w trochę inny sposób, a mianowicie poprzez zapytania Lambda, tyle że tu znowu dostaje taki komunikat:

System.Data.EntityCommandExecutionException was unhandled
  Message=Wystąpił błąd podczas wykonywania definicji polecenia. Aby uzyskać szczegółowe informacje, zobacz wyjątek wewnętrzny.
  Source=System.Data.Entity
  StackTrace:
       w System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
       w System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
       w System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
       w System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
       w System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
       w BudSystem.FormLogowanie.czyPrawidloweHaslo(String login, String haslo) w C:\Users\Szymon\Desktop\praca inż\BudSystem\FormLogowanie.cs:wiersz 47
       w BudSystem.FormLogowanie.buttonZaloguj_Click(Object sender, EventArgs e) w C:\Users\Szymon\Desktop\praca inż\BudSystem\FormLogowanie.cs:wiersz 23
       w System.Windows.Forms.Control.OnClick(EventArgs e)
       w System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       w System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       w System.Windows.Forms.Control.WndProc(Message& m)
       w System.Windows.Forms.ButtonBase.WndProc(Message& m)
       w System.Windows.Forms.Button.WndProc(Message& m)
       w System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       w System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       w System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       w System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       w System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       w System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       w BudSystem.Program.Main() w C:\Users\Szymon\Desktop\praca inż\BudSystem\Program.cs:wiersz 19
       w System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       w Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       w System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       w System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.Data.SqlClient.SqlException
       Message=The data types text and nvarchar are incompatible in the equal to operator.
       Source=.Net SqlClient Data Provider
       ErrorCode=-2146232060
       Class=16
       LineNumber=6
       Number=402
       Procedure=""
       Server=SZYMON-DELL
       State=1
       StackTrace:
            w System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
            w System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
            w System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
            w System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
            w System.Data.SqlClient.SqlDataReader.get_MetaData()
            w System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
            w System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
            w System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
            w System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
            w System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
            w System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
            w System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
       InnerException: 

a mój kod wygląda nastepująco:

private void buttonZaloguj_Click(object sender, EventArgs e)
        {    
            if (czyPrawidloweHaslo(textBoxLogin.Text, maskedTextBoxHaslo.Text) == true) Application.Run(new FormGlowne());
        }

        private bool czyPrawidloweHaslo(string login, string haslo)
        {
            BudSystemEntities bazaBudSystem = new BudSystemEntities();

            var uzytkownik = (from uzytkownicy in bazaBudSystem.Uzytkownicy
                              where (uzytkownicy.login == login) && (uzytkownicy.haslo == haslo)
                              select new
                              {
                                  uzytkownicy.login,
                                  uzytkownicy.haslo
                              }).AsEnumerable().FirstOrDefault();
            if (uzytkownik == null) return false;
            return true;
        }

Debuger od razu podświetla problem z porównywaniem string'ów poprzez "==" w zapytaniu po WHERE, ale jak próbuje z .CompareTo(...) to też nie działa. Kolumny login i hasło w bazie danych są w dalszym ciągu typu nvarchar.

0

tak, tak próbowałem, ale dalej to samo :/

0

zamień maskedTextBoxHaslo.Text i weryfikacja.haslo na tablice bajtowe i wyświetl je na formie, zobaczysz co nie gra

0

bez .AsEnumerable()
tylko .FirstOrDefault()
warunek z null ok
dygrecja:
zamiast

if (uzytkownik == null) return false;
return true;

można
return (uzytkownik != null);

co do samego "where (uzytkownicy.login == login) && (uzytkownicy.haslo == haslo)" to nie wiem co i jak przychodzi z formy, a co siedzi w bazie, ale muszą być różnice, może w kodowaniu
wpisz do tabeli na nowo loginy i hasła, bo jak wcześniej miałeś text, a zmieniłeć je na nvarchar to może coś się porąbało

0

ok, loginy i hasła przepisane w bazie i działa. Dzieki!

Teraz powstaje inny problem, a mianowicie potrzebuje aby, na formie głównym(a tak naprawde dobrze by było na wszystkich formach) mieć dostęp do rekordu który reprezentuje zalogowanego aktualnie uzytkownika, gdyż każdy uzytkownik ma przypisane id grupy użytkowników a poszczególne grupy mają mieć różne uprawnienia. W związku z tym na formie logowania napisałem sobie taka funkcję:

public string Autoryzacja(string login, string haslo)
        {
            var logowanyUzytkownik =
                (
                from uzytkownik in bazaBudSystem.Uzytkownicy
                where uzytkownik.login.Equals(login) && uzytkownik.haslo.Equals(haslo)
                select uzytkownik
                ).AsEnumerable().First();
            return logowanyUzytkownik.GrupyUzytkownikow.nazwa;
        }

a zwraca ona cały rekord, który mi potrzeba do tworzenia warunków wyswietlania poszczególnych formów itp itd...

Sama ta funkcja (nawet jak definiuje zmienną logowanyUzytkownik, która wygląda tak jak w tej funkcji, żeby nie używac procedury, dzieje się to samo) jak ją wywołuje z konkretnymi parametrami na tym samym formie(form logowania) rzuca wyjątek, ale to oddzielny temat, nie na teraz :)

Generalnie chodzi o to żeby poszczególnym grupom uzytkowników udzielać dostępu do poszczególnych form'ów. Tyle, że musze miec dostep do danych zalogowanego uzytkownika, tak naprawde w każdym miejscu aplikacji.

Czy ktoś mnie może poratować, więdzą na ten temat? Może, to powinno być całkowicie inaczej zrealizowane? Jednym słowem, za wszelką pomoc w rozwiązaniu tego problemu będę Wam bardzo wdzięczny :)

0

Zrób sobie klasę, która będzie miała właściwość typu Użytkownik. Właściwość tę ustaw przy logowaniu, a potem odwołuj się do niej gdzie chcesz. W tej klasie możesz też przechowywać inne, potrzebne w całej aplikacji rzeczy, np. konfigurację. Uwaga - należy zadbać o to, aby cała aplikacja operowała tylko na jednym obiekcie tej klasy, czyli trzeba zaimplementować wzorzec singleton.

0

Ok, wielkie dzieki za naprowadzenie. Nie czuje jeszcze za bardzo singletonów, bo nie miałem wielu okazji aby takowe pisać, w jakimś konkretnym celu, dlatego też wklejam napisany przed momentem singleton, który według mnie powinien byc dobrze.

public sealed class ClassLogIn
    {
        BudSystemEntities bazaBudSystem = new BudSystemEntities();
        string login, haslo;

        public ClassLogIn()
        {
            //konstruktor bez argumentów aby można było tworzyć obiekty tej klasy, które pozwalaja wywołać stworzony raz obiekt będący właściwością
        }

        public ClassLogIn(string _login, string _haslo)
        {
            login = _login;
            haslo = _haslo;
        }

        public Uzytkownicy ZalogowanyUzytkownik
        {
            get
            {
                return ZalogowanyUzytkownik;
            }
            set
            {
                ZalogowanyUzytkownik =
                (
                from uzytkownik in bazaBudSystem.Uzytkownicy
                where uzytkownik.login.Equals(login) && uzytkownik.haslo.Equals(haslo)
                select uzytkownik
                ).AsEnumerable().First();
            }
        }
    }

Czy tak rzeczywiście jest? Czy gdzieś popełniłem błąd?

1

No w zasadzie to zupełnie nie o to mi chodziło. W zasadzie nawet nie wiem co ten kod ma robić, zwłaszcza ten setter.

Klasa, o której pisałem, przechowująca rzeczy potrzebne w całej aplikacji:

public sealed class AppContext
{
    private static AppContext instance;
    public Uzytkownicy ZalogowanyUzytkownik { get; set; }

   private AppContext(){}

   public static AppContext Instance 
   {
       get
       {
           if (instance == null)
                instance = new AppContext();

          return instance;
       }
   }   
}

Tu jakaś metoda autoryzująca:

public void Autoryzuj(string login, string haslo) // nazwy metod to CZASOWNIKI
{
    // osobiście rzygam gdy widzę tą cudaczną składnię z from i where, więc napisałem to po ludzku:
    AppContext.Instance.ZalogowanyUzytkownik = bazaBudSystem.Uzytkownicy.FirstOrDefault(q => q.login == login && q.haslo == haslo);
}

Gdzieś indziej w kodzie dobieramy się do zalogowanego użytkownika

public void JakaśMetoda()
{
    string imię = AppContext.Instance.ZalogowanyUzytkownik.Imię;
    MessageBox.Show("Twoje imię to: " + imię);
}
0

funkcje autoryzującą umieściłem na form logowania, ale nie widzi właściwości instance, VS podpowiada tylko .Equals albo .ReferenceEquals

dopiero jak stworze nowy obiekt tej klasy np.

AppContext logowanie = new AppContext();

to dopiero na rzecz tego nowego pn. logowanie moge wywołać właściwość Instance

no ale takie wywoływanie, jak wiadomo, nie ma najmniejszego sensu

tak samo w przypdaku metody która ma się dobrać do konkretnych wartości

0

W dalszym ciągu coś nie gra. :/ Wywala definicje funkcji Autoryzuj. login i hasło są dobrze przekazywane ale AppContext.Instaance.ZalogowanyUzytkownik jest null.

Kod błędu:

Wyjątek System.Data.EntityCommandExecutionException nie został obsłużony
  Message=Wystąpił błąd podczas wykonywania definicji polecenia. Aby uzyskać szczegółowe informacje, zobacz wyjątek wewnętrzny.
  Source=System.Data.Entity
  StackTrace:
       w System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
       w System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
       w System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
       w System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
       w System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
       w System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__1[TResult](IEnumerable`1 sequence)
       w System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
       w System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression)
       w System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source, Expression`1 predicate)
       w BudSystem.FormLogowanie.Autoryzuj(String login, String haslo) w C:\Users\Szymon\Desktop\praca inż\BudSystem\FormLogowanie.cs:wiersz 25
       w BudSystem.FormLogowanie.buttonZaloguj_Click(Object sender, EventArgs e) w C:\Users\Szymon\Desktop\praca inż\BudSystem\FormLogowanie.cs:wiersz 39
       w System.Windows.Forms.Control.OnClick(EventArgs e)
       w System.Windows.Forms.Button.PerformClick()
       w System.Windows.Forms.Form.ProcessDialogKey(Keys keyData)
       w System.Windows.Forms.Control.PreProcessMessage(Message& msg)
       w System.Windows.Forms.Control.PreProcessControlMessageInternal(Control target, Message& msg)
       w System.Windows.Forms.Application.ThreadContext.PreTranslateMessage(MSG& msg)
       w System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       w System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       w System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       w System.Windows.Forms.Form.ShowDialog(IWin32Window owner)
       w BudSystem.FormGlowne.FormGlowne_Load(Object sender, EventArgs e) w C:\Users\Szymon\Desktop\praca inż\BudSystem\Form1.cs:wiersz 89
       w System.Windows.Forms.Form.OnLoad(EventArgs e)
       w System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
       w System.Windows.Forms.Control.CreateControl()
       w System.Windows.Forms.Control.WmShowWindow(Message& m)
       w System.Windows.Forms.Control.WndProc(Message& m)
       w System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       w System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       w System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd, Int32 msg, Int32 wParam, Int32 lParam)
       w System.Windows.Forms.Form.SetVisibleCore(Boolean value)
       w System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       w System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       w BudSystem.Program.Main() w C:\Users\Szymon\Desktop\praca inż\BudSystem\Program.cs:wiersz 19
       w System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       w Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       w System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       w System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.Data.SqlClient.SqlException
       Message=The data types text and nvarchar are incompatible in the equal to operator.
       Source=.Net SqlClient Data Provider
       ErrorCode=-2146232060
       Class=16
       LineNumber=20
       Number=402
       Procedure=""
       Server=SZYMON-DELL
       State=1
       StackTrace:
            w System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
            w System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
            w System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
            w System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
            w System.Data.SqlClient.SqlDataReader.get_MetaData()
            w System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
            w System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
            w System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
            w System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
            w System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
            w System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
            w System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
       InnerException: 
0

Masz jakieś dziwne typy danych.
Zamiast:

AppContext.Instance.ZalogowanyUzytkownik = bazaBudSystem.Uzytkownicy.FirstOrDefault(q => q.login == login && q.haslo == haslo);

Daj:

AppContext.Instance.ZalogowanyUzytkownik = bazaBudSystem.Uzytkownicy.FirstOrDefault(q => q.login.Equals(login) && q.haslo.Equals(haslo));
0

Nie no, próbowałem już za pomocą .Equals porównywać - w dalszym ciągu lipa :/ Pola login i hasło w bazie są typu text.

0

A tamta wersja z from...select działała?

0

daje dokładnie ten sam błąd

1

Najprostsze rozwiązanie to nie używać prehistorycznego i bezużytecznego typu text w bazie. Użyj nvarchar jak to robią ludzie.

0

Ok, zmienilem te typy danych w bazie, i porównania za pomocą == i działa!

Wielkie dzięki za okazaną pomoc! :)

0
somekind napisał(a)

Najprostsze rozwiązanie to nie używać prehistorycznego i bezużytecznego typu text w bazie. Użyj nvarchar jak to robią ludzie.

"text" nie jest prehistoryczny i bezuzyteczny, tylko sluzy do trzymania duzych ilosci tekstu. sprobuj w nvarchar wsadzic kilka kilobajtow tekstu!
na text operator =/<> na nim nie dziala, ale LIKE tak, zakladajac ze usluge fulltextsearch masz zainstalowana. po prostu te kolumny sluza kompletnie do czegos innego

0
quetzalcoatl napisał(a)

"text" nie jest prehistoryczny i bezuzyteczny, tylko sluzy do trzymania duzych ilosci tekstu. sprobuj w nvarchar wsadzic kilka kilobajtow tekstu!

W nvarchar(MAX) można włożyć i 2GB.

Prehistoryczny i bezużyteczny to oczywiście wyolbrzymienie, ale nie bez powodu - Microsoft też już ich nie lubi. ;)

ntext, text, and image data types will be removed in a future version of Microsoft SQL Server. Avoid using these data types in new development work, and plan to modify applications that currently use them.

Źródło: http://msdn.microsoft.com/en-us/library/ms187993.aspx

0

Eh, tak, masz racje, zgadza sie --- jesli używasz zawsze najnowszego mssqlservera.. Zapomnialem dorzucic dopisku o wersji.. Sprobuj wcisnac te 2gb na ss2000 albo ss2005, ktorych wszedzie wciaz pelno "bo licencja kosztuje".

1 użytkowników online, w tym zalogowanych: 0, gości: 1