F
F
Fat Lorrie2017-09-27 20:42:56
Entity Framework
Fat Lorrie, 2017-09-27 20:42:56

EF Core, many-to-many, no lazy loading repository?

We have two entities connected in m2m through the third (as in the manual ).

Entity and context code
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; }
}


I would like to do something like this
Basic repository implementation
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();
}


... but the problem is that the dependencies won't be loaded. For EF Core is not able in normal m2m and lazy loading.
There was an idea to make it virtual GetAll()and make it in the heirs to .Include()the appropriate dependencies, but even with this horror, we stumble upon a collection (joining table) and xs what to do with it. In the guides, either references to EF7 (where there is no problem as such), or no abstraction DbContextis used over it, so Includes are unrestrictedly made before the request itself.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
F
Fat Lorrie, 2017-10-25
@Free_ze

In general, it is necessary to redefine methods for the repository of each non-trivial type, pre-inclusion of all the necessary dependencies.
Unfortunately, I did not find an opportunity to write such a universal one BaseRepository.Set { get; }, so that it was only necessary to redefine (and add dependencies) to it.
With many-to-many , aliens again have nothing to do with it, and I didn’t read the documentation well, the matter is solved as follows:

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

It hurts, but you can live. Fortunately, there are not so many operations in the base repository.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question