IQueryable wewnątrz encji - Entity Framework Core

0

Mamy dwie klasy: Aggregate i Entity. Jeden Aggregate może mieć wiele Entity, przy czym Entity nie ma sensu istnienia samodzielnie bez Aggregate. Chciałbym, żeby nie było można pobrać obiektu Entity bezpośrednio z bazy danych, zatem nie będę udostępniać propercji typu DbSet<Entity> w MyDbContext. Do operacji na Entity będą służyć metody w Aggregate. To wygląda tak:

class Aggregate
{
  IEnumerable<Entity> Entities { private get; private set }; // lub ICollection<Entity>

  public bool HasSomething()
  {
    // jeśli istnieje takie i takie entity to zwróć bool
  }
}

Chciałbym np. sprawdzić, czy istnieje zadane Entity. Wiem, że w Entity Framewok mogę to skonfigurować tak by pod propercją Entities były ładowane wszystkie obiekty Entity. Problem polega na tym, że może być ich bardzo dużo, dlatego nie chcę by za każdym razem gdy ładuję Aggregate pobierana była z bazy danych lista wszystkich Entity. Zatem mogę to ustawić na virtual i wskazywać, kiedy chcę pobierać poprzez .Include(a => a.Entities). Mogę nawet robić Where by nie wczytywać wszystkiego na raz: .Include(a => a.Entities.Where(e => e));

To jest ok, ale mamy taką sytuację, że najpierw ładuję obiekt Aggregate bez Entities, a potem za jakiś czas chcę sprawdzić, czy Entities zawiera zadany element. Niestety nie mogę tego zrobić, bo obiekt Aggregate ma pustą listę Entities. Mogę na nowo załadować obiekt Aggregate ze wskazanym Entity, ale wolałbym tego uniknąć.

Teraz pytanie: czego potrzebuję? Chciałbym skonfigurować Entities w Aggregate w taki sposób by zachowywało się jak IQueryable. Tzn. ładuję obiekt Aggregate z pominięciem ładowania obiektów Entity, a potem w metodzie HasSomething() będę mógł sobie zrobić np. Entities.Any(e => e.Value == 10); Dopiero w momencie wykonania tego Any() idzie zapytanie SQL do bazy danych. Czy jest to możliwe?

Z perspektywy klienta klasy Aggregate chciałbym by wyglądało to, jak zwykły obiekt przechowywany w pamięci RAM, a nie klasa napisana pod Entity Framework dlatego użycie DbSet (o ile można użyć w encji) odpada. W ogóle idealnie byłoby nie importować jakiejkolwiek zależności z EF.

Obecnie Entity ma swoje repozytorium, niestety inny programista może użyć tego w zły sposób dlatego chciałbym ograniczyć wszystkie operacje na Entity (tworzenie, usuwanie, modyfikowanie) by działy się za pośrednictwem Aggregate w jego metodach.

2

Możesz skorzystać z ILazyLoader https://docs.microsoft.com/en-US/dotnet/api/microsoft.entityframeworkcore.infrastructure.ilazyloader?view=efcore-5.0
Coś na ten sposób:

class Aggregate
{
    public Aggreagte(ILazyLoader lazyLoader)
    {
    }
    
    private IEnumerable<Entity> _enitites;
    public IEnumerable<Entity> Entities
    {
        get => LazyLoader.Load(this, ref _enitites);
        set => _enitites= value;
    }

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