Entity Framework 核心、工作单元和存储库模式

Entity Framework Core, Unit of Work and Repository Pattern

阅读了大量文章指出不建议将 UOW 和存储库模式置于 EF Core 数据库上下文之上,我几乎同意并准备在一个新项目中实施注入 IDBContext 的服务我的

我说差不多,因为我以前使用过一个功能,但我不明白如果没有存储库如何实现。

在以前的项目中,我在 EF 上使用了 UOW 和存储库模式,并从服务访问它们。以下方法将在存储库中,之后可以通过从任何服务调用 uow.StudentRepository.Get(id) 来调用。

public async Task<Student> Get(Guid id)
    {
        return await _context.Students
            .Include(x => x.Course)
            .Include(x=>x.Address)
            .Include(x => x.Grade)
            .FirstOrDefaultAsync(x => x.Id == id);
    }

如果没有存储库,从 IDBContext 查询,我将不得不调用...

_context.Students
            .Include(x => x.Course)
            .Include(x=>x.Address)
            .Include(x => x.Grade)
            .FirstOrDefaultAsync(x => x.Id == id);

...每次我想做这个查询。这似乎是错误的,因为它不会干。

问题

有人可以建议我可以在没有存储库的情况下在一个地方声明此代码的方法吗?

听起来您需要服务。您可以创建 DbContext 之类的服务,以便将其注入控制器。

IStudentService.cs:

public interface IStudentService
{
    Task<List<Student>> GetStudents();
    // Other students methods here..
}

StudentService.cs

public class StudentService : IStudentService
{
    private readonly DataContext _context;

    public StudentService(DataContext context)
    {
        _context = context;
    }

    public async Task<List<Student>> GetStudents()
    {
        return await _context.Students
        .Include(x => x.Course)
        .Include(x=>x.Address)
        .Include(x => x.Grade)
        .ToListAsync();
    }
}

然后在Startup.cs

中将服务注册到ConfigureServices()
services.AddScoped<IStudentService, StudentService>();

现在您可以将服务注入任何控制器。示例:

[ApiController]
[Route("api/[controller]")]
public class StudentController: ControllerBase
{
    private readonly IStudentService _studentService;
    private readonly DataContext _context;

    public StudentService(DataContext context, IStudentService studentService)
    {
        _context = context;
        _studentService = studentService;
    }

    [HttpGet]
    public virtual async Task<IActionResult> List()
    {
        return Ok(await _studentService.GetStudents());
    }
}

确保仅当您将在多个控制器上使用它时才创建该服务并避免陷入反模式。