Использование DTO с OData в .NetCore 2.1 - PullRequest
0 голосов
/ 20 июня 2019

Я пишу тестовый OData Rest API с базой данных InMemoryDatabase. Я хотел бы использовать DTO, чтобы скрыть модель SQL и настроить несколько полей (географическое положение и т. Д.). Однако когда я использую метод ProjectTo<...> из AutoMapper, запрос GET к API возвращает пустую коллекцию вместо фактического списка результатов.

Ты хоть представляешь, что я делаю не так?

Вот контроллер:

namespace offers_api.Controllers
{
    public class OffersController : ODataController
    {
        private readonly OfferContext _context;
        private IMapper _mapper;

        public OffersController(OfferContext context, IMapper mapper)
        {
            _context = context;
            _mapper = mapper;
        }

        [EnableQuery]
        public IActionResult Get()
        {
            IQueryable<Offer> res = _context.Offers.ProjectTo<Offer>(_mapper.ConfigurationProvider); // <-- works without ProjectTo !
            return Ok(res);
        }
    }
}

Объявление автомпера:

namespace offers_api.Entities
{
    public class Mapping : Profile
    {
        public Mapping()
        {
            //CreateMap<CategoryEntity, string>().ConvertUsing(cat => cat.Name ?? string.Empty);
            CreateMap<LocationEntity, Location>()
                .ForMember(x => x.longitude, opt => opt.MapFrom(o => 0))
                .ForMember(x => x.latitude, opt => opt.MapFrom(o => 0))
                .ReverseMap();
            CreateMap<OfferEntity, Offer>()
                .ForMember(x => x.Category, opt => opt.MapFrom(o => o.Category.Name))
                .ReverseMap()
                .ForMember(x => x.Category, opt => opt.MapFrom(o => new CategoryEntity { Name = o.Category }));
            CreateMap<OfferPictureEntity, OfferPicture>().ReverseMap();
            CreateMap<UserEntity, User>().ReverseMap();
        }
    }
}

Модель EDM:

private static IEdmModel GetEdmModel()
{
    ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
    builder.EntitySet<Offer>("Offers");
    return builder.GetEdmModel();
}

1 Ответ

0 голосов
/ 20 июня 2019

Я нашел решение.

Фактически, автоматический загрузчик загружает больше данных, чем поведение OData по умолчанию. Отношение между предложением и его автором было описано ненулевым первичным ключом. Я не вставил ни одного автора в БД, но OData попыталась загрузить пользователя и обнаружила, что его нет в таблице USER, поэтому он отбросил результат предложения.

Решение: сделать внешний ключ обнуляемым.

namespace offers_api.Entities
{
    public class OfferEntity
{
        [Key]
        public long Id { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public long AuthorId { get; set; } // <== Bug here : add long? to resolve it...
        public virtual UserEntity Author { get; set; }
    }
}
...