Posts Tagged ‘.net’

The easiest way to log the user

Author: Krzysztof Wawoczny (Krzysztof Wawoczny) | April 26th, 2010

Obecnie w niemal każdej aplikacji biznesowej wymagane jest zalogowanie się by w pełni móc korzystać z możliwości jakie taka aplikacje daje, lub by wogóle móc cokolwiek zrobić. Jakiś czas temu zrobiłem krótki research po sieci w poszukiwaniu jakiegoś sprytniejszego rozwiązania niż to które używam w swoich aplikacjach. Cóż…dziwni są ludzie którzy zatrudniają do obrony swojego zamku legiony, a pozwalają do niej wejść zwykłym OR 1=1 (to tak na marginesie), nie rozumię też rozwiązania które zostało pozytywnie ocenione na jednym z for programistycznych a wygląda ono tak:
W aplikacji sprawdzamy czy ustawiony jest w bazie znacznik informujący o zalogowaniu, jeśli nie to po zalogowaniu generujemy go, a usuwamy go gdy użytkownik zamknie aplikację…a co jeśli zwiesi się komp, zabraknie prądu albo wydarzy się coś innego ? Przecież po wystąpieniu tak nieoczekiwanego zdarzenia wartość w bazie może się nie zmienić a wtedy każdy kto skorzysta z komputera będzie zalogowany. Naprawdę nie rozumię wielu tych wielkich idei, dlatego na razie nadal korzystam z bardzo prostego rozwiązania które wygląda następująco:

W aplikacji w sekcji odpowiedzialnej za przechowanie predefiniowanych zmiennych globalnych (jak np. nazwa bazy, string wyświetlany w górnej belce aplikacji etc.), ustawiam sobie zmienną określającą czy użytkownik jest zalogowany (domyślnie ustawioną na false), oraz metodę pozwalającą zmienić wartość tej zmiennej:

public class GlobalAppVariables
{
    /// Globalna zmienna której wartość jest ustwaiona na 1 gdy użytkownik się zaloguje.
    static int _logged = 0;

    /// Dostęp/zmiana wartości globalnej zmiennej _logged
    public static int Logged
    {
      get
      {
        return _logged;
      }
      set
      {
        _logged = value;
      }
    }
}

Samo logowanie polega na wywołaniu metody która połączy się z bazą, sprawdzi czy dla podanych parametrów istnieje wpis i na tej podstawie zwrócie wynik pozytywny/negatywny co zkolei pozwoli mi ustawić wartość zmiennej _logged w następujący sposób:

private void button1_Click(object sender, EventArgs e)
{
    object result = Queries.StartSession(this.loginTxt.Text, this.PasswordTxt.Text);
   //Queries to osobna klasa w której przechowywane są metody odpowiedzialne za oberacje na bazie
    if (result != null)
    {
        this.Close(); //zamknięcie okna logowania
        GlobalAppVariables.Logged = 1; // w tej chwili wiem że już mam zalogowanego użytkownika
    }
    else
    {
       //info o nieudanym logowaniu
    }
}

Jeśli już mam zalogowanego użytkownika mogę odblokować domyślnie wyłączone opcje, lub zrobić coś innego.
Jeśli niepotrzebujesz wymyślnego systemu logowania skorzystaj z przedstawionego sposobu, jest on wystarczający dla wielu nieskomplikowanych aplikacji. AVE!

NHibernate’s Cascade wonder… and pain

Author: Adam Ludera (Luder) | November 13th, 2009

As could be found from Mateusz posts, we are really into Rhino and NHibernate usage. With a bit of doubt we started using quite interesting feature called cascade. By its name you can easily say what is it all about. Think of, for example, relation one-to-many, which basically means IList<T> in your parent class and reference in child one. Map (using Fluent NHibernate) would be nothing else then:

1. Parent:

HasMany(x => x.Childs).KeyColumnNames.Add("ParentId");

2. Child:

References(x => x.Parent, "ParentId").Not.Nullable();

On regular basis to create a parent with 2 children you would have to do something like:

var parent = new Parent() ;
Repositories.ParentRepository.Save(parent);

var child1 = new Child();
var child2 = new Child();
child1.Parent = child2.Parent = parent;
parent.Add(child1);
parent.Add(child2);

Repositories.ChildRepository.Save(child1);
Repositories.ChildRepository.Save(child2);
Repositories.ParentRepository.Update(parent);

Pretty dull, isn’t it? But if you go and modify your Parent Map to:

HasMany(x => x.Childs).KeyColumnNames.Add("ParentId").Cascade.SaveUpdate();

then you can do same with way fewer lines:

var parent = new Parent() ;
var child1 = new Child();
var child2 = new Child();

child1.Parent = child2.Parent = parent;
parent.Add(child1);
parent.Add(child2);

Repositories.ParentRepository.Save(parent);

How’s that?

All these coding savings are because NHib by its own checks content of Childs list once Parent gets saved or updated.
Today I went one step forward and wanted to use cascade for deletion. And it is where the pain starts :] Analogically to above code you would think to try removing children like this:

Parent.Childs.Remove(child1);

or

Parent.Childs.Clear(); //to remove all - this is actually what I was trying to do

After this you get this pretty nice exception:

NHibernate.Exceptions.GenericADOException: could not delete collection rows: [Child][SQL: UPDATE Child SET ParentId = null WHERE ParentId = @p0 AND Id = @p1] —> System.Data.SqlClient.SqlException: Cannot insert the value NULL into column ‘ParentId’, table ‘db.dbo.Child’; column does not allow nulls. UPDATE fails

A minute had to pass till I realized I was being stupid – Map says:

HasMany(x => x.Childs).KeyColumnNames.Add("ParentId").Cascade.SaveUpdate();

so why would NHib delete anything for me? There must be another option to force it to remove entities automatically. This option is called AllDeleteOrphan(). Setting this option for a bag means that if Child is removed reference from Parent it will automatically be deleted once Session flushes. However having Map like this:

HasMany(x => x.Childs).KeyColumnNames.Add("ParentId").Cascade.AllDeleteOrphan();

will fail due to same error as before.

Problem here is that NHib does first removes reference (set NULL) and once this is done tries to DELETE. Due to FK constraint it fails though.

To force NHib to “remember” about FK constraint we have to set bidirectional association. To do this just add .Inverse() option right after cascade spec, so Map will be:

HasMany(x => x.Childs).KeyColumnNames.Add("ParentId").Cascade.AllDeleteOrphan().Inverse();

That does the trick and now you can remove child entities by simply removing reference to parent, so:

Parent.Childs.Remove(child1);

or

Parent.Childs.Clear();

works like a charm ;]

Norwegian Developer’s Conference

Author: Mateusz Kubiczek (madmatt) | July 7th, 2009

Wow – just wow.

Take a look at what happened up north a few weeks ago: http://www.ndc2009.no/en/.

Why don’t we get conferences like this in our part of Europe?? Well, neither the distance nor the price an excuse for not having been there.

The agenda was just amazing: http://www.ndc2009.no/en/agenda.aspx?cat=1071&id=1813&day=3727.

So many .NET and Agile gurus, and so many interesting topics. What’s even nicer, is that they posted most of the presentations online – something that’s been happening very often recently (check out PDC2009!) with the most prominent conferences.

I just started watching Roy Osherove’s “Unit Testing Best Practices” presentation. You can watch it here (windows media unfortunetely for mac users, get flip4mac). I’m halfway through it and, what’s quite nice, is that we’ve already been doing most of the stuff he covered. Guess I should post about this soon. :-)

Using Active Record to write less code

Author: Mateusz Kubiczek (madmatt) | April 22nd, 2009

Ayende Rahien posted a great presentation on Active Record: http://www.viddler.com/explore/oredev/videos/89. He argues that persistence is a solved problem, and it’s hard to disagree after watching it! Only recently we have started using NHibernate for persistence and we’re loving it. Maybe ActiveRecord would have had a flatter learning curve?