@Free_ze
Пишу комментарии в комментарии, а не в ответы

EF Core, many-to-many, репозиторий без lazy loading?

У нас есть две сущности, связанных в m2m через третью (как по мануалу).
Код сущностей и контекста
class MyContext : DbContext
{
    public DbSet<Post> Posts { get; set; }
    public DbSet<Tag> Tags { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<PostTag>()
            .HasKey(t => new { t.PostId, t.TagId });

        modelBuilder.Entity<PostTag>()
            .HasOne(pt => pt.Post)
            .WithMany(p => p.PostTags)
            .HasForeignKey(pt => pt.PostId);

        modelBuilder.Entity<PostTag>()
            .HasOne(pt => pt.Tag)
            .WithMany(t => t.PostTags)
            .HasForeignKey(pt => pt.TagId);
    }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public List<PostTag> PostTags { get; set; }
}

public class Tag
{
    public string TagId { get; set; }

    public List<PostTag> PostTags { get; set; }
}

public class PostTag
{
    public int PostId { get; set; }
    public Post Post { get; set; }

    public string TagId { get; set; }
    public Tag Tag { get; set; }
}


Хотелось бы сделать что-то такое
Базовая реализация репозитория
public abstract class BaseRepository<TEntity>
            where TEntity : class
{
    protected readonly MyDbContext _context;
    protected DbSet<TEntity> Set => _context.Set<TEntity>();

    public BaseRepository(MyDbContext context)
    {
        _context = context;
    }

    public IQueryable<TEntity> GetAll()
    {
        return Set.AsQueryable();
    }

    public TEntity GetById(int id)
    {
        return Set.Find(id);
    }

    public void Commit() => _context.SaveChanges();
}



... но проблема в том, что не будут загружены зависимости. Ибо EF Core не умеет в нормальный m2m и ленивую загрузку.

Была идея делать виртуальным GetAll() и в наследниках делать .Include() к соответствующим зависимостям, но даже при этом ужасе мы натыкаемся на коллекцию (соединительной таблицы) и хз, что делать с этим. В гайдах либо отсылки к EF7 (где проблемы нет как таковой), либо никакой абстракции над DbContext не используется, поэтому Include невозбранно делаются перед самим запросом.
  • Вопрос задан
  • 558 просмотров
Решения вопроса 1
@Free_ze Автор вопроса
Пишу комментарии в комментарии, а не в ответы
В общем, приходится для репозитория каждого нетривиального типа переопределять методы, предварительно подынклуживая все необходимые зависимости.
К сожалению, не нашел возможности написать такой универсальный BaseRepository.Set { get; }, чтобы переопределять (и доинклуживать зависимости) необходимо было только в него.

С many-to-many опять инопланетяне непричем, а я плохо читал документацию дело решается следующим образом:

_context.Posts.Include(p => p.PostTags)
                  .ThenInclude(pt => pt.Tag);

Больно, но жить можно. Благо, что операций в базовом репозитории не так уж много.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы