#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