C# - konwencje nazewnicze oraz korzystanie z NHibernate

0

Witajcie ostatnio piszę sobie malutki programik i mam taką oto klasę.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IvoiceObjectsLib
{
    class Invoice
    {
        private int _id;
        private DateTime _date;
        private string _number;
        private int _clientId;
        private int _workerId;
        private decimal _discount;
        private int _paymentType;
        private decimal _total;
        private int _recivedById; 

        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }
       

        public DateTime Date
        {
            get { return _date; }
            set { _date = value; }
        }
       

        public string Number
        {
            get { return _number; }
            set { _number = value; }
        }
       

        public int ClientId       //Klucz obcy
        {
            get { return _clientId; }
            set { _clientId = value; }
        }


        public int WorkerId   // klucz obcy
        {
            get { return _workerId; }
            set { _workerId = value; }
        }

        public decimal Discount
        {
            get { return _discount; }
            set { _discount = value; }
        }

        public int PaymentType   //klucz obcy
        {
            get { return _paymentType; }
            set { _paymentType = value; }
        }

        public decimal Total
        {
            get { return _total; }
            set { _total = value; }
        }

          public int RecivedById   //klucz obcy
        {
            get { return _recivedById; }
            set { _recivedById = value; }
        }

    }
}
 

I teraz mam pytanko (to jest czysto teoretyczne ale nie wiem jak jest ładniej)
Pasuje mi nazwać taki klucz ale jak?

mam kilka możliwości:

Właściwość: **FkClientId **, pole prywatne **_fkClientId **(Wygląda głupio ale CamelCase' owo)

Właściwość: FK_Client_Id // a może tak ( duże literki/ FK nazwa tabeli /Nazwa klucza)
pole prywatne: _fk_client_id

Jak nazywacie takie "klucze obce" :)

0

Nie jestem pewien, jak jest w C#, natomiast w Pascalu często oznacza się to jako F (od słówka field) + nazwa pola, np.:
private int FNumber;
A potem getter oraz setter o nazwie Number i po sprawie ;)

0

doSZEDŁem do wniosku że tak będzie ładnie:

    
     public int FK_ClientId
        {
            get { return _fk_clientId; }
            set { _fk_clientId = value; }
        }

Przy czym przyjąłem nazewnictwo FK_NazwaTabeliId.
Przy czym w bazie każde pole ma klucz o nazwie "id" jako główny.
chętne bym się dowiedział jaka jest konwencja nazewenicta kluczy obcych.
(Każda firma ma pewnie wlasną ale może istnieje jakiś "standard".

0
property -> PascalCase
variable -> camelCase

Pisania podkreslen odrzuca :(

3

Ale po co w ogóle tak robić?

 class Invoice
    {
        public int Id { get; set; }
        public DateTime Date { get; set; } 
        public string Number { get; set; }
        public int ClientId { get; set; }
        public int WorkerId { get; set; }
        public decimal Discount { get; set; } 
        public int PaymentType { get; set; } 
        public decimal Total { get; set; } 
        public int RecivedById { get; set; }
    }
0

@Azarien, ok a jak chce już zaimplementować sobie taki akcesor to wtedy muszę go rozwinąć do postaci :

private int  id;
    public int Id
            {
                get { return id* 2; }
                set { id = value; }
            }

Czy mogę to jakoś "skrócić"? bo faktycznie tam gdzie nie implementuje akcesora mogę zrobić wersję skróconą ale tam gdzie już go implementuje to nie wiem. Jeszcze wracając do pytanka jeszcze Jak ładnie oznaczyć w kodzie klucz obcy? przy properties dać FK_nazwa czy FkNazwa czy jakoś inaczej - chcę aby było jak najlepiej sformatowane:)

0

NazwaTabeliId

Poza tym stosuj automatyczne properties albo publiczne pola, po co pisać 40 linii kodu skoro możesz to samo zawrzeć w 8? Dzięki temu zyskujesz na czytelności i widać, że jeżeli jest getter/setter, to faktycznie coś robi.

0
public string ImieMarudy {get;set;} 

taki krótki kawałek kodu generuje w kodzie CIL: prywatne pole, oraz dwie publiczne metody oznaczone kolejno _get oraz _set :). Czyli generalnie kompilator oszczędza Ci pisania kodu.
Z doświadczenia Ci powiem, ze właściwości automatyczne czasem naprawdę się przydają bo np. aplikacje mobilne nie obsługują jakiś rzeczy, które może np. jakiś setter implementować.

0
SiSzarpany napisał(a):

bo faktycznie tam gdzie nie implementuje akcesora mogę zrobić wersję skróconą ale tam gdzie już go implementuje to nie wiem.

Wrzuciłeś kod, w którym nigdzie nie masz specyficznej implementacji akcesora, więc nie ma sensu nie stosować automatycznych właściwości. Rozwijaj tam, gdzie faktycznie chcesz dopisać coś konkretnego.

Jeszcze wracając do pytanka jeszcze Jak ładnie oznaczyć w kodzie klucz obcy?

Wcale?
Klucze obce występują w bazie danych, nie w pisanym obiektowo programie.

0

Dobrze dziękuję za odpowiedzi. A teraz już ostatnie pytanko. Piszę aplikację z użyciem NHibernate. Jak wiadomo
W NHibernate tworzymy obiekt **ISession **na podstawie ISessionFactory I teraz zastanawia mnie problem organizacji kodu.
Otóż klasy wrzuciłem sobie do osobnego projektu.
Aby nie tworzyć w kółko obiektów typu ISession stworzyłem sobie zmienne w głównym wątku programu
ISession oraz ISessionFaktory
I teraz wszystko by było fajnie gdyby nie to że muszę do tych klas dopisać metody, które operowałyby na zmiennych ISession.
Aby ładnie podzielić kod mam do wyboru:
Rozwiązanie 1.
dla każdej klasy **KlasaA , KlasaB, KlasaC ** zrobić konstruktor który pobierałby przez referencję połączenie a potem na tym operował już wewnątrz klasy
na tym połaczeniu.

Coś jak:

ISession Sesja;

KlasaA = new KlasaA(Sesja);  //pobieram przez referencję połączenie a potem wewnątrz klasy coś na nim robię

Lub Rozwiązanie 2
Stworzyć klasę bazową dla wszystkich klas, która miała by funkcję łaczenia się z bazą a wszystkie klasy dziedziczyły by po niej
Wówczas Byłoby coś w stylu

KlasaA = new KlasaA();  

KlasaA.JakasTamMetoda();   //tutaj łaczenie i rozłaczenie wewnątrz metody na podstawie dziedziczonej funkcji (jakieś tam connect i disconnect)

Rozwiązanie 1 jest fajne , ale dziwnie wygląda.
Rozwiązanie 2. nie jest takie fajne bo otwieram i zamykam połaczenie (wolniej).
Z tego co mi się wydaje najlepiej by było zrobić według rozwiązania 1. czy mam rację czy tak lepiej nie robić i jednak nawiązywać polaczenie ponownie.
Wiem że można tak i tak ale jakoś nie wiem które wyjście jest najrozsądniejsze względem późniejszego rozbudowywania programu.
Zwykle pisząc używałem Rozwiazania nr 1 ale teraz się "uczepiłem" poprawności kodu względem dalszej rozbudowy.

0
  1. Globalne ISession? Przecież instancję sesji tworzy się oddzielnie dla każdej czynności. Na tym z grubsza polega Unit of Work.
  2. Twój problem rozwiązałoby użycie jakiegoś kontenera IoC, który wstrzykiwałby ISession do wszystkich klas, w których go potrzebujesz.
  3. O jakie łączenie i rozłączanie Ci chodzi? Przecież to robi NHibernate. :|
0

Obecnie robię to tak:

  static ISessionFactory SessionFactory;
        static ISession OpenSession()
        {
            if (SessionFactory == null) 
                Configuration configuration = new Configuration();
                configuration.Configure();
             configuration.AddAssembly(Assembly.GetCallingAssembly());
                SessionFactory = configuration.BuildSessionFactory();
            }
            return SessionFactory.OpenSession();
        }
         
 using (ISession session = OpenSession())
                {
                    using (ITransaction transaction = session.BeginTransaction())
                    {
                        session.Save(JakisTamObiekt);    // i tu jakieś tam czynności w transakcji
                        transaction.Commit();
                    }
                 
                }
            }

I chodzi mi o to że za każdym razem używam OpenSession następnie coś tam robię a w innej metodzie znowu otwieram session coś tam robię itd.
I wydaje mi się że optymalnie byłoby użyć raz:

 ISession session = OpenSession() 

a następnie przekazywać taki otwarty obiekt session dla wszystkich instancji klas w projekcie.
a wewnątrz przykładowej klasy operować tylko na otwartym objekcie session.
Tak więc chciałbym wspódzielić otwartą sesję między wszystkimi klasami działającymi na Bazie danych.

0
SiSzarpany napisał(a):

Tak więc chciałbym wspódzielić otwartą sesję między wszystkimi klasami działającymi na Bazie danych.

Ale po co? Przecież to będzie niewydajne i błędogenne. To SessionFactory ma być jedno w całej aplikacji, natomiast Session ma być za każdym razem na nowo tworzone, a nie współdzielone.

Niech Twoje klasy mają konstruktory przyjmujące ISession i przekazuj im sesję w momencie ich tworzenia. Możesz to robić "ręcznie", a możesz skonfigurować kontener IoC, żeby to robił za Ciebie.

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