I use ASP.NET Core for the backend of my Azure App Service app. For each table in the database, I create a controller which acts as an API endpoint for that table. There are no problems with the code but for every Controller, I an repeating the same logic except for the Include(m => m.<Property>). Is there a way I can move all these logic into the parent TableController class and have the Include() method stuff in the model class?
These are some sample files:
Table Controller (parent class for all API controllers):
using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc;
namespace Backend.API
{
    public abstract class TableController<T> : Controller
    {
        // Public Methods
        [HttpGet]
        [Route("")]
        public abstract Task<IActionResult> GetAllAsync();
        [HttpPost]
        [Route("")]
        public abstract Task<IActionResult> CreateAsync([FromBody] T created);
        [HttpGet]
        [Route("{id}")]
        public abstract Task<IActionResult> GetAsync(string id);
        [HttpPatch]
        [Route("{id}")]
        public abstract Task<IActionResult> UpdateAsync(string id, [FromBody] T updated);
        [HttpDelete]
        [Route("{id}")]
        public abstract Task<IActionResult> DeleteAsync(string id);
    }
}
A sample Model:
using System;
using System.ComponentModel.DataAnnotations;
namespace Backend.Models.DB
{
    public class BlogPost
    {
        // Public Properties
        public DateTime DatePublished { get; set; }
        public Guid Id { get; set; }
        [Required]
        public string Body { get; set; }
        [Required]
        public string Title { get; set; }
        public string DatePublishedString =>
            string.Format("Posted on {0}.", DatePublished.ToString().ToLower());
        [Required]
        public User Publisher { get; set; }
        // Constructors
        public BlogPost() : this(null, null, null, new DateTime()) { }
        public BlogPost(BlogPost post) :
            this(post.Title, post.Body, post.Publisher, post.DatePublished) { }
        public BlogPost(string title, string body, User publisher, DateTime datePublished)
        {
            Title = title;
            if (datePublished == new DateTime())
                DatePublished = DateTime.Now;
            else
                DatePublished = datePublished;
            Body = body;
            Publisher = publisher;
        }
        // Public Methods
        public void Update(BlogPost updated)
        {
            Body = updated.Body;
            Title = updated.Title;
        }
    }
}
A sample Controller:
using System;
using System.Threading.Tasks;
using Backend.Models.DB;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Backend.API
{
    [Route("tables/BlogPost")]
    public class BlogPostController : TableController<BlogPost>
    {
        // Private Properties
        private readonly BadmintonClubDBDataContext _db;
        // Constructors
        public BlogPostController(BadmintonClubDBDataContext db) => _db = db;
        // Overridden Methods
        public override async Task<IActionResult> GetAllAsync()
        {
            var posts = await _db.BlogPosts
                .Include(bp => bp.Publisher)
                .ToArrayAsync();
            return Json(posts);
        }
        public override async Task<IActionResult> CreateAsync([FromBody] BlogPost created)
        {
            if (!ModelState.IsValid)
                return BadRequest();
            BlogPost post = (await _db
                .AddAsync(new BlogPost(created))).Entity;
            await _db.SaveChangesAsync();
            return Json(post);
        }
        public override async Task<IActionResult> GetAsync(string id)
        {
            BlogPost post = await _db.BlogPosts
                .Include(bp => bp.Publisher)
                .SingleOrDefaultAsync(bp => bp.Id == new Guid(id));
            if (post == null)
                return NotFound();
            return Json(post);
        }
        public override async Task<IActionResult> UpdateAsync(string id, [FromBody] BlogPost updated)
        {
            BlogPost post = await _db.BlogPosts
                .Include(bp => bp.Publisher)
                .SingleOrDefaultAsync(bp => bp.Id == new Guid(id));
            if (post == null)
                return NotFound();
            if (post.Id != updated.Id || !ModelState.IsValid)
                return BadRequest();
            post.Update(updated);
            await _db.SaveChangesAsync();
            return Json(post);
        }
        public override async Task<IActionResult> DeleteAsync(string id)
        {
            BlogPost post = await _db.BlogPosts
                .FindAsync(id);
            if (post == null)
                return NotFound();
            _db.BlogPosts.Remove(post);
            await _db.SaveChangesAsync();
            return Ok();
        }
    }
}
Looking at the sample controller, I have moved most of the logic into the model through methods like Update() and the constructors. How do I also move the logic for the Include() methods to my model as well?
 
     
    