ORM - mapowanie

0

Witam,
Mam problem podczas wywoływania metody z WebService.
Mam połączenie z serwisem, i z baza ale niestety pojawia się błąd podczas mapowania rekordu do obiektu.
Przynajmniej tak mi się wydaje :P a oto komunikat który dostaje.

"An unhandled exception of type 'System.ServiceModel.CommunicationException' occurred in mscorlib.dll
Additional information: Połączenie podstawowe zostało zakończone: Połączenie, które miało być aktywne, zostało przerwane przez serwer."

Uzywam Entity Framework .

Niestety odpytanie wujka gogle niewiele pomogło :/ ktoś ma jakiś pomysł ?
Program wywala się na linijce

Wywołanie Webservice:

static void Main(string[] args)
        {
            string log = "kam";
            string pass = "d968a18370429ceee4e7fb0268ec50bf";


            var klient = new uslugaTest.AuthClient();
            
            Console.WriteLine(klient.Zaloguj(log,pass));

            var obiekt = new uzytkownik();
            obiekt = klient.Zaloguj2(log,pass);
            Console.Write(obiekt.Imie);
}
 

WebService :

 
  public class Auth : IAuth
    {
        private MySqlConnection _conn;
        public bool polaczBaza()
        {
            try
            {
                _conn = new MySqlConnection(ConfigurationManager.ConnectionStrings["localConnection"].ToString());
                _conn.Open();

            }
            catch (Exception)
            {
                return false;
            }
            
            return true;
        }

    


        public bool Zaloguj(string login, string hash)
        {
            if (!polaczBaza())
            {
                return false;
            }


            using (var db = new testEntities())
            {
                var contact = db.uzytkownik
                    .Where(s => s.Login.Contains(login))
                    .Where(s => s.Hash.Contains(hash))
                    .First<uzytkownik>();

                if (contact != null)
                {
                    return true;
                }
                return false;

            }
        }

        public uzytkownik Zaloguj2(string login, string hash)
        {
        

            using (var db = new testEntities())
            {
                var query = db.uzytkownik
                        .Where(s => s.Login == login)
                         .Where(s => s.Hash.Contains(hash))
                        .FirstOrDefault<uzytkownik>();

                return query;
            }
        }
1

Albo public bool polaczBaza() i _conn są zbędne, albo new testEntities() powinieneś robić z _conn. EF z MSSQL sam sobie otwiera połączenie na podstawie danych z web.config/app.config, connector dla MySQL pewnie zapewni to samo, bo na wierzchu siedzi ten sam EF. Zgaduję, że masz nieprawidłowy connection string.

Popraw

  var query = db.uzytkownik
                        .Where(s => s.Login == login)
                         .Where(s => s.Hash.Contains(hash))
                        .FirstOrDefault<uzytkownik>();

na

var user = db.uzytkownik.FirstOrDefault(s => s.Login == login && s.Hash == hash);

Technicznie zadziała to prawie tak samo, ale

  1. typ generyka w FirstOrDefault jest zbędny
  2. Contains to fatalny pomysł, hasz ma się równać haszowi, a nie zawierać w nim (fatalne wydajnościowo, bo zostanie zamienione na like '%twójhash%' i stanowi pewną dziurę w zabezpieczeniach)
  3. na kiego grzyba where.where.firstordefault? Kod nie jest bardziej czytelny od tego.
 var obiekt = new uzytkownik();
obiekt = klient.Zaloguj2(log,pass);

Na co ten new uzytkownik();? BTW właściwa nazwa dla obiektu z użytkownikiem to "obiekt", czy "uzytkownik", a może "user"?
Nie stosuj polskich nazw, bo oczy pękają.

                var contact = db.uzytkownik
                    .Where(s => s.Login.Contains(login))
                    .Where(s => s.Hash.Contains(hash))
                    .First<uzytkownik>();
 
                if (contact != null)
                {
                    return true;
                }

First nigdy nie zwróci null'a (chyba, że null będzie wyszukanym elementem). Z tego powodu if (contact != null) zawsze będzie spełnione. Za to jeśli login lub hash nie będą się zgadzać, to poleci wyjątek. Co Ty znowu z tymi Contains? Będziesz mieć jednego usera "marianna", drugiego "anna" i ten drugi nigdy nie zaloguje się na swoje konto.
Praca domowa: czym się różni FirstOrDefault od First, czym Single od SingleOrDefault, czym First od Single oraz czym FirstOrDefalut od SingleOrDefault, ponadto różnice między .Where(...).First() a .First(...) oraz pomiędzy .Where(a => warunekA).Where(a => warunekB) od .Where(a => warunekA && warunekB).

0

no tak _conn jest nie potrzebne zostało po wcześniejszych modyfikacjach

Zazwyczaj zapisuje klasy i metody publiczne z dużej ale tutaj visual studio wygenerował mi wszystkie nazwy zaczynające się z małej
gdyby nie tak to bym zapisal pewnie var użytkownik = new Uzytkownik();

Wyczytałem że do mojego przypadku bardziej pasuje First :

– First(lambda) – zwracająca pierwszy element, który spełnia warunek podany jako wyrażenie lambda

– FirstOrDefault(lambda) – prawie to samo co wyżej, z tą różnicą, że jeśli żaden element nie spełnia warunku to nie zostanie rzucony wyjątek tylko funkcja zwróci null

Niestety po zmianie na
var user = db.uzytkownik.First(s => s.Login == login && s.Hash == hash);

nadal wywala ten sam błąd więc chyba nie w tym tkwi problem :/

0

No to akurat oczywiste, problem jest na etapie łączenia z bazą danych i/lub wykonania zapytania (a nie jego generowania przez linq) i to napisałem w pierwszym akapicie swojego posta: "zgaduję, że masz nieprawidłowy connection string". Możesz też mieć nieprawidłową konfigurację samej bazy danych lub uprawnienia (vide "Połączenie, które miało być aktywne, zostało przerwane przez serwer").
W którym dokładnie momencie leci wyjątek? polaczBaza() wykonuje się bez rzucania wyjątku? Możesz na zwróconym połączeniu wykonać sql (SqlCommand)?

Wyczytałem że do mojego przypadku bardziej pasuje First :
– First(lambda) – zwracająca pierwszy element, który spełnia warunek podany jako wyrażenie lambda
– FirstOrDefault(lambda) – prawie to samo co wyżej, z tą różnicą, że jeśli żaden element nie spełnia warunku to nie zostanie rzucony wyjątek tylko funkcja zwróci null

Źle wyczytałeś, bo wykonujesz First, a oczekujesz zachowania z FirstOrDefault. Albo rób First i łap wyjątek, albo użyj FirstOrDefault i sprawdzaj null. Niemniej nie ma to w tej chwili żadnego znaczenia, bo to miejsce będzie Ci sprawiać problemy dopiero jak już uda Ci się połączyć z MySQL przez EF.

0

Sprawdziłem polaczenie z bazą za pomocą takiej metody dopisanej w Webservice

  public string TestConnectionEF()
        {
            var db = new testEntities();
            try
            {
                db.Database.Connection.Open();
               
            }
            catch (SqlException)
            {
                return "nie";
            }
            string tekst = "INFO: ConnectionString: " + db.Database.Connection.ConnectionString
                           + "\n DataBase: " + db.Database.Connection.Database
                           + "\n DataSource: " + db.Database.Connection.DataSource
                           + "\n ServerVersion: " + db.Database.Connection.ServerVersion
                           + "\n TimeOut: " + db.Database.Connection.ConnectionTimeout;
            db.Database.Connection.Close();
            return tekst;

Wywołanie :

 
    static void Main(string[] args)
        {
            string log = "kam";
            string pass = "d968a18370429ceee4e7fb0268ec50bf";

            var klient = new uslugaTest.AuthClient();

             Console.WriteLine(klient.TestConnectionEF());
         
           var  obiekt = klient.Zaloguj2(log, pass);
                     Console.ReadKey();

oto efekt:
https://zapodaj.net/a27127bff8de1.jpg.html

I niestety nadal nie wiem gdzie tkwi błąd, no bo połączenie z bazą jest. I wywala na linijce gdy probuje pobrać obiekt.
Czy db.Database.Connection.Open(); muszę podawać z "ręki" ? czy połączenie samo się otwiera gdy buduje LINQ ?

Dodatkowo sprawdziłem czy mogę się dostać do tej bazy za pomocą sqlcommand itd. i mam dostęp, mogę pobierać bez problemu.

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