Twoim bezpośrednim problemem jest prawdopodobnie nieprawidłowy ciąg połączenia lub serwer bazy danych jest niedostępny. Ciąg połączenia powinien wyglądać mniej więcej tak
Server=localhost;Database=testdb;Uid=<username>;Pwd=<password>;
z
i
Poza tym twój kod ma kilka problemów i zdecydowanie powinieneś się im przyjrzeć, jeśli ma to stać się kodem produkcyjnym i prawdopodobnie nawet jeśli jest to tylko zabawkowy projekt, aby się czegoś nauczyć. Lista jest uporządkowana i może nie być wyczerpująca.
- Nie koduj na stałe ciągu połączenia. Zamiast tego przenieś go do pliku konfiguracyjnego.
- Nie umieszczaj haseł w postaci zwykłego tekstu w plikach konfiguracyjnych ani w kodzie źródłowym. Istnieją różne rozwiązania, takie jak uwierzytelnianie systemu Windows, certyfikaty lub chronione hasłami przez Windows Data Protection API .
- Nie wyrzucaj
IDisposable
instancje, wywołującIDisposable.Dispose()
. Zamiast tego użyjusing
oświadczenie o zwolnieniu zasobów nawet w przypadku wyjątków. - Nie twórz instrukcji SQL przy użyciu technik manipulacji ciągami. Zamiast tego użyj
SqlParameter
aby zapobiec atakom typu SQL injection. - Nie przechowuj haseł w postaci zwykłego tekstu w bazie danych. Zamiast tego przynajmniej przechowuj solone skróty haseł i używaj powolnej funkcji skrótu, a nie MD5 lub członka Rodzina SHA.
- Możesz użyć
IDbCommand. ExecuteScalar
aby pobrać wynik skalarny i uniknąć używania czytnika danych. - Porównywanie wartości logicznej z
true
lubfalse
jest zbędny i po prostu dodaje szum do twojego kodu. Zamiastif (reader.IsDBNull(0) ==true)
możesz po prostu użyćif (reader.IsDBNull(0))
. To samo dotyczyif (reader.Read() !=false)
co jest równoważne zif (reader.Read() ==true)
a zatem takżeif (reader.Read())
. - Korzystanie z mapera O/R, takiego jak Entity Framework jest zwykle preferowany w stosunku do interakcji z bazą danych na poziomie poleceń SQL.