//Na początku chce uciąć dyskusję dlaczego nie korzystam od razu z ORM'a a tak archaicznie podchodze do wspolpracy z baza danych.
Porównując, żeby nauczyć się jezdzic na rowerze z przerzutkami dobrze jest najpierw nauczyc się dobrze chodzić.
Po prostu EF czy LINQtoSQL za dużo od razu ukrywały, nie do konca wiedzialem co gdzie i dlaczego, dlatego chce sie najpierw przeczołgac tym sposobem. co nie znaczy ze kiedys sobie to przepisze tego z uzyciem jakiegos ORM'a.//
Witam
Jak w tytule mam pytanie czym właściwie jest Agregat w podejsciu DDD, i jak go właściwie zaimplementować w moim projekcie?
Fragment bazy do którego chce podejsc jak do DDD:
http://4programmers.net/Forum/Bazy_danych/223722-relacje_zamykaja_tabele_bazy_w_petli_-_czy_to_jest_poprawne
I teraz tak, na razie zdefiniowałem anemiczne encje:
-DzialFirmy
-Stanowisko
-Uprawnienie
-Pracownik
Przykład mojej encji:
public class PracownikEntity : BaseEntity
{
public string Imie1 { get; set; }
public string Imie2 { get; set; }
public string Nazwisko { get; set; }
public string Login { get; set; }
public string MailFirmowy { get; set; }
public string Telefon1 { get; set; }
public string Telefon2 { get; set; }
public int? IdBezposredniegoPrzelozonego { get; set; }
public int? IdZajmowanegoStanowiska { get; set; }
public int? IdDzialuFirmowego { get; set; }
public DateTime? DataZatrudnienia { get; set; }
public DateTime? DataZwolnienia { get; set; }
}
Dodałem 4 odpowiadające encjom, Repository jako warstwa dostępu do bazy danych. I na razie Repository zwracają obiekty moich anemicznych encji.
Przykład mojego repozytorium:
public class PracownikRepository : IBaseRepository<PracownikEntity>
{
SqlConnection conn;
//Pozostałe metody dziedziczone po IBaseRepository
//Przykład Add(entity)
public void Add(PracownikEntity entity)
{
//wyciągnąłem do osobnego obiektu i w jednym miejscu zmieniam connection string zaleznie na ktorym komputerze aktualnie pracuje
using (conn = new SqlConnection(DataBaseConnection.connString))
{
conn.Open();
string sql = "INSERT INTO " +
"Pracownik(Imie1, Imie2, Nazwisko, Login, mailFirmowy, telFirmowy1, " +
"telFirmowy2, idPrzelozonego, idDzialu, idStanowiska, DataZatrudnienia, DataZwolnienia) " +
"VALUES (@Imie1, @Imie2, @Nazwisko, @Login, @MailFirmowy, @Telefon1, " +
"@Telefon2, @idPrzelozonego, @idDzialu, @idStanowiska, @DataZatrudnienia, @DataZwolnienia)";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("@Imie1", entity.Imie1);
cmd.Parameters.AddWithValue("@Imie2", DBTools.GetDBNULLableValue(entity.Imie2));
cmd.Parameters.AddWithValue("@Nazwisko", entity.Nazwisko);
cmd.Parameters.AddWithValue("@Login", entity.Login);
cmd.Parameters.AddWithValue("@MailFirmowy", DBTools.GetDBNULLableValue(entity.MailFirmowy));
cmd.Parameters.AddWithValue("@Telefon1", DBTools.GetDBNULLableValue(entity.Telefon1));
cmd.Parameters.AddWithValue("@Telefon2", DBTools.GetDBNULLableValue(entity.Telefon2));
cmd.Parameters.AddWithValue("@idPrzelozonego", DBTools.GetDBNULLableValue(entity.IdBezposredniegoPrzelozonego));
cmd.Parameters.AddWithValue("@idDzialu", DBTools.GetDBNULLableValue(entity.IdDzialuFirmowego));
cmd.Parameters.AddWithValue("@idStanowiska", DBTools.GetDBNULLableValue(entity.IdZajmowanegoStanowiska));
cmd.Parameters.AddWithValue("@DataZatrudnienia", DBTools.GetDBNULLableValue(entity.DataZatrudnienia));
cmd.Parameters.AddWithValue("@DataZwolnienia", DBTools.GetDBNULLableValue(entity.DataZwolnienia));
cmd.ExecuteNonQuery();
conn.Close();
}
}
}
public interface IBaseRepository<T> where T : BaseEntity
{
T GetById(int id);
List<T> GetAll();
int Count();
void Add(T entity);
void Update(T entity);
void Remove(T entity);
}
public static class DBTools
{
public static object GetDBNULLableValue(object value)
{
if (value == null)
{
return DBNull.Value;
}
return value;
}
}
Z tego co na razie się naczytałem, to Agregat rozumiem jako coś w rodzaju kontenera związanych ze sobą encji z jedną encją nadającą "charakter przewodni" dla agregatu. Dla swojego przypadku wydaje mi się że to będą agregaty:
-PracownikAgregat
-StanowiskoAgregat
Odpowiednio agregat PracownikAgregat, bedzie miał w sobie obiekt Stanowiska, **Dzialu **, Przelozonego i listę nadanych Uprawnien, bo encja wyciaga tylko ID dla tych pól.
Agregat StanowiskoAgregat bedzie mial liste obiektów Uprawnienie Domyslne dla Stanowiska i operacje na nich, dodawania, usuwanie itp.
I teraz pytanie:
Czy repository powinno zwracac od razu agregaty? tzn swoje encje mam rozwinąc, dodać do nich metody, zamiast id wyciągac od razu obiekty za pomocą innych repositoriów (np. PracownikRepository bedzie zawieralo i korzystalo z DzialRepository itp.)
czy
PracownikAgregat bedzie oddzielnym obiektem ktory bedzie zawieral przekazywana przez konstruktor encje i "opakuje" pola encji wlasnymi wlasciwosciami tylko od odczytu i metodami z logika zmieniajaca wartosci tych pól?