Entity framework included properties and Repository pattern

c# entity-framework-core repository-pattern

Question

I have, say, a database containing tables Forums and Topics. Each topic has a foreign key to its parent forum.

Their associated C# models are Forum and Topic and Forum has an ICollection pointing to its child topics. I have a Forum repository which I use to directly access entity framework's context and I only return Forum / IEnumerable from it. The rest of the application only accesses the database through this repository. My question is the following: at some point in time, I want to get, say, all forums from the database without populating the Topics property. To do this, I'd have to have a method GetAll that'd do this: return _context.Forums.ToList();.

But now suppose that I also want at some point to return all forums, but with their Topics property populated. I guess I could create a new method in the repository (called GetAllForumsWithTopics or something), but it seems weird to create a new method every time I want to include more fields (maybe at some point I also want to include a property for the topic, say its list of Posts.. then I'd have to go like GetAllForumsWithTopicsWithPosts?).

So, I'd like to somehow define a method GetAllForums("includelist") [EDIT: I actually wouldn't like a string as the parameter, but a lambda expression :)] method that would allow me to include properties down the hierarchy (not only for the Forums themselves). What would be a good way of doing that?

1
0
2/8/2019 3:29:14 AM

Popular Answer

Probably a good idea to write out the code you're attempting to do. The way I'm reading this is that you have something like the following:

public class Forum
{
    public int Id {get; set;}
    public IEnumerable<Topic> Topics {get; set;}
}

public class Topic
{
    public int Id {get; set;}
    public Forum Forum {get; set;}
}

There are a few ways to solve this. It sounds like you already know the difference between Virtual and Non-Virtual, when it comes to how eager it loads the contents. You can selectively include child elements using the Include property (see: https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx)

Personally, the route I'd probably approach this is in my EF implementation class (that implements an interface that's used elsewhere) to have two get methods:

public virtual IQueryable<Forum> Forums => _context.Forums;
public virtual IQueryable<Forum> ForumsWithChildren => _context.Forums.Include(m => m.Topic)

In a "real world" application of this, there should be a time limiter, and only pulling the topics by a specific forum call:

public virtual Forum GetForumWithRecentPosts(int id)
{
    //Add where clause to restrict based off date.
    return Forums.Where(x => x.Id == id).include(m => m.Topic);
}
2
1/24/2018 10:30:12 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow