Использование OData Expand с DTOC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Использование OData Expand с DTO

Сообщение Anonymous »

Я получил этот простой API в .NET 8, добавил пакеты Mediatr и OData, а также AutoMapper
Я стараюсь не раскрывать данные своего уровня данных на уровне API, поэтому все нужно делать через посредник запросы.
Ниже приведены мои сущности, контроллер и обработчик запросов.
// Сущности

Код: Выделить всё

public class Course : BaseAuditableEntity
{
public string? Name { get; set; }
public Guid StudentId { get; set; }
public virtual Student? Student { get; set; }
}

public class Student : BaseAuditableEntity
{
public string? Name { get; set; }
public virtual ICollection Courses{ get; private set; } = new List();
}
// Запрос и обработчик посредника

Код: Выделить всё

public record GetRawCoursesQuery : IRequest;

public class GetCoursesQueryHandler : IRequestHandler
{
private readonly IApplicationDbContext _context;
private readonly IMapper _mapper;

public GetCoursesQueryHandler(IApplicationDbContext context, IMapper mapper)
{
_context = context;
_mapper = mapper;
}

public Task Handle(GetRawCoursesQuery request, CancellationToken cancellationToken)
{
return Task.FromResult(_context.Courses.AsQueryable());
}
}
// Действие контроллера

Код: Выделить всё

[HttpGet("odata")]
[EnableQuery]
public async Task GetCoursesAsync(
[FromQuery] int top,
[FromQuery] int skip,
[FromQuery] string orderby,
[FromQuery] string filter,
[FromQuery] string expand)
{

var query = await _sender.Send(new GetRawCoursesQuery());

return Ok(query);

}
// GetEdmModel в Program.cs

Код: Выделить всё

private static IEdmModel GetEdmModel()
{
var builder = new ODataConventionModelBuilder();
builder.EntitySet("Courses");
var course = builder.EntityType();
course.ContainsOptional(t => t.Student);
builder.EntitySet("Students");

return builder.GetEdmModel();
}
Таким образом, вышеописанное работает отлично: я могу фильтровать, могу выбирать и, самое главное, могу расширять. Все работает так, как ожидалось.
Кроме того, если кому-то интересно, почему в моем действии используется FromQuery, они необходимы, поскольку я использую NSwag для создания своего APIClient, и это единственный способ для NSwag увидеть конечную точку OData!
Проблема:
Вышеупомянутое работает нормально, однако оно работает нормально, потому что я использую ' Объекты «Курс» и «Студент», но мне нужно, чтобы это использовало DTO, однако когда я это делаю, все работает, кроме Развернуть
Вот изменения, которые я внес

Код: Выделить всё

private static IEdmModel GetEdmModel()
{
var builder = new ODataConventionModelBuilder();
builder.EntitySet("Courses");
var course = builder.EntityType();
course.ContainsOptional(t => t.Student);
builder.EntitySet("Students");

return builder.GetEdmModel();
}

public record GetRawCoursesQuery : IRequest;

public class GetCoursesQueryHandler : IRequestHandler
{
private readonly IApplicationDbContext _context;
private readonly IMapper _mapper;

public GetCoursesQueryHandler(IApplicationDbContext context, IMapper mapper)
{
_context = context;
_mapper = mapper;
}

public Task Handle(GetRawCoursesQuery request, CancellationToken cancellationToken)
{
return Task.FromResult(_mapper.ProjectTo(_context.Courses));
}
}

public class CourseDto
{
public string? Name { get; set; }
public Guid StudentId { get; set; }
public virtual StudentDto? Student { get; set; }
private class Mapping : Profile
{
public Mapping()
{
CreateMap()
.ForMember(dest => dest.Student, opt => opt.ExplicitExpansion());

}
}

}

public class StudentDto
{
public string? Name { get; set; }

private class Mapping : Profile
{
public Mapping()
{
CreateMap();
}
}

}
И никаких изменений в действии контроллера, поскольку оно ничего не ссылается на Entity или Dto!
Все работает нормально, кроме Expand, когда я вызываю URL-адрес типа
https://localhost:5001/odata/Courses?expand=Student
, который, как ожидается, включите Student в возвращаемый результат внутри объекта Course, но Student возвращает значение null!
Похоже, что проблема может быть связана с ProjectTo, я проверил это, включив свойство вручную в ProjectTo и это сработало, поэтому я думаю, что OData нужно каким-то образом сообщить ProjectTo о включении расширенных свойств!
Буду признателен, если кто-нибудь поможет мне понять, в чем здесь проблема!

Подробнее здесь: https://stackoverflow.com/questions/784 ... -with-dtos
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»