Pobieranie DI z klasy bazowej

0

Witam.
W związku z tym, że piszę pod Comarch Optima, muszę wymyślać różnego rodzaju obejścia na ułatwienie sobie przyszłej pracy i rozbudowywania projektu z jednoczesnym zachowaniem wydajności tego systemu. Używam Dappera. Nie korzystam z EF, bo nie ma "custom query", a też, najważniejsze, korzystam z gotowej bazy oraz inserty robię przez .dll samej Optimy, więc po co EF...

Próbuje zrobić coś na wzór EF. Główny dbContext i konkretne "tabelki" oraz ich podstawowe opcje (add, edit, delete, get, getsingle).

    public interface IDatabaseContext
    {
        public AttributesEntity Attributes { get; set; }
    }

    public class DatabaseContext : IDatabaseContext
    {
        private readonly IDbConnectionFactory _dbConnectionFactory;
        private readonly IHttpContextAccessor _httpContextAccessor;

        public DatabaseContext(IDbConnectionFactory dbConnectionFactory, IHttpContextAccessor httpContextAccessor)
        {
            _dbConnectionFactory = dbConnectionFactory;
            _httpContextAccessor = httpContextAccessor;
        }

        public AttributesEntity Attributes { get; set; }
    }

Tabelka atrybutów

    public interface IAttributesEntity
    {
        Task<IEnumerable<DefAttribute>> Get(string query, object param);
        Task<DefAttribute> GetSingle(string query, object param);

        int Add(DefAttribute attribute);
        bool Update(DefAttribute attribute);
        bool Delete(DefAttribute attribute);
    }

Takich tabelek oczywiście będzie/jest masa. Na tę chwilę mam ich 9, w których potrzebuje obsłużyć podstawowe operacje. Zauważyłem, że to nie bardzo pomaga mi w klepaniu tego samego i muszę do każdej tabelki dopisywać DI z IDbConnectionFactory oraz IHttpContextAccessor. Da się ogarnąć to tak, aby IAttributesEntity miało dostęp do tych dwóch?

PS.
Z IHttpContextAccessor pobieram claims na temat wybranej firmy (bazy danych). Można mieć kilka firm/baz w Optimie + osobno baza konfiguracyjna, w której są użytkownicy i ich ustawienia.
Z IDbConnectionFactory tworze połączenie do odpowiedniej bazy (firma, konfiguracja) i przekazuje do Dappera.

0

A co to jest DefAttribute i jakie jest powiązanie między IAttributesEntity i DatabaseContext?
Do czego w ogóle służy IAttributesEntity?

0

DefAttribute to encja (nie wiem czy dobrego terminu użyłem), klasa które reprezentuje Atrybuty w bazie Comarch Optima. Używa się tego, aby dopisywać do dokumentów, towarów oraz kontrahentów jakiś niestandardowych danych. To jest tylko przykład. Ja wszystkie obiekty chce tak zrobić. Może nazewnictwo nie jest zbyt odpowiednie, tylko ja w tym grzebie i nie zapowiada się na więcej osób.

A więc:

  1. DefAttribute - obiekt w bazie
  2. IAttributesEntity - coś na zasadzie DbSet w EF, tutaj jest cała logika związana z obiektami DefAttribute - dodawnia, edycja, usuwanie oraz pobieranie
  3. DatabaseContext - coś na zasadzie DbContext z EF, połączenie z bazą, ma trzymać wszystkie obiekty takie jak IAttributesEntity

Wtedy po stronie kontrollera mogę sobie zrobić:

_dbContext.Attributes.Add();
_dbContext.Attributes.Get("select * from CDN.TwrAtrybuty");

Jeszcze mam zamiar powalczyć z parametrami z pomocą SqlKata. Tego już jest bardzo dużo (jak dla mnie), a projekt nawet nie jest w połowie.

0

Ok, czyli IAttributesEntity to jest kolekcja, a nie jedna rzecz - zmyliła mnie nieco liczba pojedyncza w nazwie.
Oryginalny DbSet jest generyczny. Ty jak rozumiem nie chcesz/nie możesz mieć generycznie, chcesz mieć oddzielny interfejs dla każdej tabeli. No i w sumie tu się rodzi moje pytanie - skoro nie chcesz ORMa, bo go nie potrzebujesz, to czemu chcesz, aby to, czego potrzebujesz wyglądało jak ORM? Mnie to wygląda na utrudnianie sobie nieco życia.

No i głównego problemu też chyba nie rozumiem - masz jakiś obiekt opakowujący tabelę w bazie, ten obiekt wymaga IDbConnectionFactory oraz IHttpContextAccessor do działania, więc jakoś musisz je przekazać - najlepiej przez konstruktor.
No i najlepiej chyba wszystkie te obiekty typu AttributesEntity utworzyć w konstruktorze DatabaseContext, zamiast robić im publiczne setery.

0

To nie jest tak, że nie potrzebuje ORMa. Ja potrzebuje narzędzia, które będzie "ORMem" ale da mi większą swobodę niż EF. Do tej pory Microsoft nie potrzebuje robić w EF Core FromSql z poziomu DbContext, działa to tylko na tabeli, a ja tego potrzebuje. Druga sprawa to tabele w Optimie mają po kilkadziesiąt kolumn i durne nazwy tych kolumn.

Żeby zobrazować jaki bajzel teraz jest to mam to zrobione tak:

  1. AttributesController - kontroler do atrybutów, który ma wstrzyknięte AttributesService
  2. AttributesService - serwis, który ma wstrzyknięty SqlService oraz OptimoService
  3. SqlService - serwis do zapytań o dane (nie ma insertów, update'ów itp)
  4. OptimoService - serwis do obsługi insertów, update'ów wykorzystujący "API" Comarchu
    Dodatkowe
  5. IQueryService - serwis, który trzyma warunki SQL do każdego możliwego obiektu (różnice w nazwach kolumn), w tym jest też paginacja i sortowanie
  6. IQueryGenerator - "serwis" do tworzenia zapytań SQL. Oprócz zapytania o listę obiektów, generuje też zapytania o ilość danych (count(*)) z zastosowanym filtrem. Oraz generuje też zapytania do danych dodatkowych. W przypadku dokumentów jest to suma marży, netto, brutto itp. W przypadku płatności jest suma przychodów, rozchodów itp.

Może masz jakiś inny sposób na uproszczenie tego procesu. Każdy kolejny obiekt, który muszę obsłużyć powoduje, że muszę w każdym z wymienionych coś dopisać. Tego jest za dużo. Projekt będzie cały czas rozwijany, dopisywane będą kolejne funkcjonalności z Optimy, a ja sobie prędzej w łeb strzelę niż ogarnę cokolwiek w tym bałaganie.

0

OData + https://github.com/AutoMapper/AutoMapper.Extensions.OData nie wystarczy? Po co samemu sqele rzeźbić?

0

Nie mam dużego doświadczenia w tym typie projektów. Do tej pory projekty były małe, proste i miałem swoją bazę, którą byłem w stanie ogarnąć w 100% za pomocą EF, albo Dapper nie wymagał taki durnych kombinacji. W tym momencie zatrzymałem się na Dapperze i SqlKata. Jestem w stanie ogarnąć paginację, sortowanie oraz dynamiczne warunki? Przykładowo mam

public class DocumentFilter 
{
    public int Page {get;set;}
    public int Limit {get;set;}
    public string Direction {get;set;}
    public string Active {get;set;}
    public string Search {get;set}
    public DateTime DateStart {get;set;}
    public DateTime DateEnd {get;set;}
    public string Corrected {get;set;} // ma trzy stany o wartości - crossed (checked+unchecked),checked,unchecked
    public string Canceled {get;set;} // ma trzy stany o wartości - crossed (checked+unchecked),checked,unchecked
}

Na tę chwilę w serwisie IQueryService ogarniam logikę warunków i generuje odpowiednie SQL.

0

Czy ja dobrze rozumiem, że AttributesControler i AttributesService są związane z obrabianiem konkretnej tabeli natomiast cała reszta: SqlService, OptimoService, IQueryService, IQueryGenerator są wspólne dla wszystkich tabel?

0

Zgadza się...
https://tenor.com/blCyf.gif

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