ASP.NET 核心 API oData 和 API 层模型

ASP.NET Core API oData and API layer model

我需要在 ASP.NET 核心应用程序中为我的 API 端点使用 OData,但所有示例都是关于直接使用数据模型 classes。在我的应用程序架构中,我有服务层,此服务的方法 return DTO classes 然后映射到 API 视图 classes.

我的数据class(基础设施层):

public partial class Carrier : BaseEntity
{
    public string Name { get; set; }
    public string Code { get; set; }
    public string UsDotNumber { get; set; }
    public string McNumber { get; set; }

我的 DTO class:

public class CarrierBaseDto
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Code { get; set; }
    public string Fein { get; set; }
    public string McNumber { get; set; }

我的演示文稿 (API) class:

public class CarrierAPI
{
    [JsonProperty(PropertyName = "name")]
    public string Name { get; set; }
    [JsonProperty(PropertyName = "code")]
    public string Code { get; set; }
    [JsonProperty(PropertyName = "fein")]
    public string Fein { get; set; }
    [JsonProperty(PropertyName = "mcNumber")]
    public string McNumber { get; set; }

我的服务方式:

    public List<CarrierBaseDto> SearchCarriersDto()
    {
        var query = _context.Carriers
            .Where(c => !c.Deleted);

        IQueryable<CarrierBaseDto> queryDto = query.ProjectTo<CarrierBaseDto>(_mapperConfig);
        return queryDto.ToList();
    }

我的控制器方法:

    [HttpGet]
    [Route("GetAll")]
    public IActionResult GetAll()
    {
        var carriers = _carrierService.SearchCarriersDto();
        var carriersApi = _mapper.Map<List<CarrierElementAPI>>(carriers);
        return new OkObjectResult(carriersApi);
    }

我想添加使用 $orderBy$filter$fields 参数的功能。如何将它添加到我当前的架构中?

我认为当他们最初设计 OData 时,它不打算在没有 DDD 的情况下使用,因为元数据应该允许您处理过滤器等,这现在对使用它产生了一些限制。

有一些棘手的解决方法,但它们只能部分起作用。我能想到的最接近的事情是通常接受查询选项并应用它们,然后使用 automapper 投影到您的可查询,

唯一的问题是在您的自动映射器设置中从实体到 DTO 的映射不能复杂,必须通过表达式映射

设置
public Object[] Get(ODataQueryOptions<ProductDTO> options)
{
    ODataQuerySettings settings = new ODataQuerySettings()
    {
        PageSize = 5
    };

    IQueryable results = options.ApplyTo(_products.AsQueryable().ProjectTo<ProductDTO>(), settings);

    results.ToArray()
}