Как вернуть другой тип объекта на основе условия в HTTP-ответе (.net core)

#c# #entity-framework #.net-core #automapper #generic-list

#c# #entity-framework #.net-core #automapper #общий список

Вопрос:

У меня есть один класс модели EF, один DTO BaseClass и один DTO AdminClass , который простирается от BaseClass . Я получаю свои данные из EF и использую класс AutoMapper для преобразования в соответствующий объект, используя приведенный ниже код.

 public async Task<object> GetItems()
{
    object nearestItems = _dbContext.Items.ToList(); // Gets it from DBContext.Items....
    var dtoList = IsAuthenticated ? MapObject<IEnumerable<AdminClass>>(nearestItems) : MapObject<IEnumerable<BaseClass>>(nearestItems);
    return dtoList;
}

private T MapObject<T>(object obj)
{
    object convertedObject = null;
    //convertedObject = IsAuthenticated ? _mapper.Map<IList<AdminClass>>(obj) : _mapper.Map<BaseClass>(obj);
    return (T)convertedObject;
}
  

Но это возвращает только BaseClass свойства, когда ответ отправляется обратно, даже если он аутентифицирован и должен возвращать AdminClass свойства вместе с BaseClass . Чтобы вернуть соответствующий объект, я должен использовать условие If / Else, а не троичный оператор и должен использовать AdminClassWithoutBaseClass для возврата всех свойств. Хотя и не идеально, потому что после мне нужно выполнить некоторые другие манипуляции, но это работает. Тем не менее, я хотел бы знать, как я могу заставить его работать с вышеуказанным синтаксисом, а также, есть ли аккуратный способ его написания.

Вы можете увидеть пример кода на Dotnetfiddle.

Ответ №1:

Это звучит как проблема с отложенной загрузкой. В .net Core вы должны включить отложенную загрузку расширенных свойств с помощью прокси. Вот подробный пост в блоге об этом:https://www.learnentityframeworkcore.com/lazy-loading

Вам нужно будет добавить Microsoft.Пакет nuget EntityFrameworkCore.Proxy и включите его при создании экземпляра вашей контекстной службы.

 services.AddDbContext<SomeContext>(options =>
    options.UseLazyLoadingProxies());
  

Комментарии:

1. Я не думаю, что это должно быть связано с EF или отложенной загрузкой, чтобы быть конкретным. Список уже кэширован в памяти (с использованием кэширования .net core), и данные уже преобразованы в соответствующий тип. Проблема в том, что когда HTTP-ответ отправляется обратно, он возвращает только свойства базового типа.

2. Итак, если вы введете точку останова и посмотрите, что возвращается из кэша, прежде чем оно будет отправлено в качестве http-ответа, оно действительно содержит значения AdminClass?

3. К вашему сведению, кэш предназначен для списка EF, поэтому мне не нужно совершать обходы в БД. И да, я вижу список AdminClass здесь return list; в действии контроллера, но в списке базовых классов ответа.

4. Вы женаты на идее использования automapper? Я могу выполнить ручное преобразование. Полный пример слишком длинный для комментария…

5. Рабочий пример ручного преобразования на dotnetfiddle