首页 > 解决方案 > 清洁代码问题:EF Core 参数化要包含的属性

问题描述

这个问题是关于干净的代码和最佳实践的。我们正在使用.NET Core 3.1开发 Web 应用程序。假设我们有PostsControllerwhich 接受请求,它从数据库和具有某些属性的数据库模型PostService返回一些数据。Post

public class PostsController : Controller
{
    private readonly IPostsService _postsService;

    public PostsController(IPostsService postsService)
    {
        _postsService = postsService;
    }

    public IActionResult Get(int id)
    {
        Post post = _postsService.Get(id);
        return View(post);
    }
}

public class PostsService : IPostsService
{
    private readonly MyDbContext _dbContext;

    public PostsService(MyDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public Post Get(int id)
    {
        return _dbContext.Post
            .Include(x => x.FirstPropery)
            .FirstOrDefault(x => x.Id == id);
    }
}

一切都很好,对吧?但是假设有另一个控制器(或另一个服务,并不重要)也调用_postsService.Get(id)但它不需要Postjust FirstProperty。它还需要它的SecondPropery. 因此,适当的服务功能将是:

public Post Get(int id)
{
    return _dbContext.Post
        .Include(x => x.FirstPropery)
        .Include(x => x.SecondPropery)
        .FirstOrDefault(x => x.Id == id);
}

想象一下,可能有n控制器都需要 Post by its Id,但每个控制器都需要自己包含的属性。

在这种情况下我们应该怎么做?

  1. 创建n不同的服务方法,每个方法都返回具有不同包含属性的帖子?丑陋的。
  2. 创建一个包含ALL属性的通用服务方法?丑,慢,很多属性都不需要。
  3. ... ?

有没有办法对Include你需要的 s 进行参数化?我不想硬编码任何字符串属性,因为它会导致很多错误。我需要一个干净的解决方案,如果我们更改模型中某些属性的名称,它会产生编译时错误Post

标签: c#entity-frameworkasp.net-core

解决方案


想象一下,可能有 n 个控制器都需要按其 Id 发布,但每个控制器都需要自己包含的属性。

这就是为什么您的控制器应该有权访问IQueryable<Post>. 这是允许控制器指定查询的类型。您建议的替代方案只是一个非常有限的本土 API,可让控制器控制查询。


推荐阅读