简体   繁体   English

清洁代码问题:EF Core 参数化要包含的属性

[英]Clean code question: EF Core parametrize which properties to include

This question is about clean code and best practices.这个问题是关于干净的代码和最佳实践的。 We are using .NET Core 3.1 to develop a web application.我们正在使用.NET Core 3.1开发 web 应用程序。 Let's say we have PostsController which accepts requests, PostService which returns some data from the database and Post database model with some properties.假设我们有接受请求的PostsController 、从数据库返回一些数据的PostService和具有一些属性的Post数据库 model。

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);
    }
}

Everything fine, right?一切都很好,对吧? But let's say that there is another controller (or another service, doesn't really matter) which also calls _postsService.Get(id) but it doesn't need Post with just FirstProperty .但是,假设还有另一个 controller (或其他服务,并不重要)也调用_postsService.Get(id)但它不需要PostFirstProperty It also needs its SecondPropery .它还需要它的SecondPropery So appropriate service function for it would be:因此,适当的服务 function 将是:

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

Imagine that there could be n controllers all needing Post by its Id , but each needing its own included properties.想象一下,可能有n控制器都需要按其Id发布,但每个控制器都需要自己包含的属性。

What should we do in this case?在这种情况下我们应该怎么做?

  1. Create n different service methods, each of them returning post with different included properties?创建n不同的服务方法,每个方法都返回具有不同包含属性的帖子? Ugly.丑陋的。
  2. Create a general service method which includes ALL properties?创建一个包含ALL属性的通用服务方法? Ugly, slow, many properties are not needed.丑,慢,很多属性都不需要。
  3. ... ? ... ?

Is there a way to parametrize which Include s you need?有没有办法对您需要的Include进行参数化? I don't want to hardcode any string properties since it can lead to many errors.我不想硬编码任何字符串属性,因为它会导致很多错误。 I need a clean solution which would produce compile time error if we change a name of some property in Post model.如果我们在Post model 中更改某些属性的名称,我需要一个干净的解决方案,它会产生编译时错误。

Imagine that there could be n controllers all needing Post by its Id, but each needing its own included properties.想象一下,可能有 n 个控制器都需要按其 Id 发布,但每个控制器都需要自己包含的属性。

This is why your controllers should have access to an IQueryable<Post> .这就是为什么您的控制器应该有权访问IQueryable<Post>的原因。 That's the type that allows the controller to specify the query.这是允许 controller 指定查询的类型。 The alternative you are suggesting is just a very limited, home-grown API to give the controller control over the query.您建议的替代方案只是一个非常有限的本土 API 让 controller 控制查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM