Отложенная загрузка не поддерживается для отдельных сущностей или сущностей, загружаемых с помощью AsNoTracking

Я использую Entity Framework в качестве ORM для SQL Server.

Это код внутри моего POST API:

var group = await _context.Groups.FindAsync(id);
            
foreach (CalendarRuleGroup calendarRuleGroup in group.CalendarRuleGroups)
{
    CalendarRule calendarRule = _context.CalendarRules
        .Where(cr => cr.CalendarRuleGroupId == calendarRuleGroup.Id)
        .First();
    
    CalendarRule calendarRuleTemp = (CalendarRule)calendarRule.Clone();
    _context.CalendarRules.Add(calendarRuleTemp);
}

await _context.SaveChangesAsync();

Это функция Clone():

public object Clone()
{
    CalendarRule clonedRule = (CalendarRule)MemberwiseClone();
    clonedRule.Calendar = null;
    clonedRule.CalendarId = default;
    clonedRule.CalendarRuleGroup = null;
    clonedRule.CalendarRuleGroupId = default;
    clonedRule.CalendarContexts = null;
    clonedRule.Id = default;
    List<CalendarRuleCondition> conditions = new List<CalendarRuleCondition>();
    
    foreach (CalendarRuleCondition condition in clonedRule.CalendarRuleConditions)
    {
        conditions.Add((CalendarRuleCondition)condition.Clone());
    }
    
    clonedRule.CalendarRuleConditions = conditions;
    return clonedRule;
}

Это модель CalendarRule:

public class CalendarRule: ICloneable
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime StartingFrom { get; set; }
    public DateTime? Until { get; set; }
    public int? Count { get; set; }
    public double Duration { get; set; }
    public Frequency Frequency { get; set; }
    public int Interval { get; set; }
    public int Priority { get; set; }
    public bool IsWorking { get; set; }
    public int Efficiency { get; set; }
    public int Cost { get; set; }
    public bool AllowedSetup { get; set; }
    public int Color { get; set; }
    public string Description { get; set; }
    public bool? IsActive { get; set; }
    public int CalendarId { get; set; }
    public int? CalendarRuleGroupId { get; set; }
    public virtual Calendar Calendar { get; set; }
    public virtual CalendarRuleGroup CalendarRuleGroup { get; set; }
    public virtual ICollection<CalendarContext> CalendarContexts { get; set; }
    public virtual ICollection<CalendarRuleCondition> CalendarRuleConditions { get; set; }
}

И это ошибка, которая появляется, когда выполняется «clonedRule.CalendarRuleConditions» внутри foreach:

fail: Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HMG79T5K5ECK", Request id "0HMG79T5K5ECK:00000002": An unhandled exception was thrown by the application.
      System.InvalidOperationException: An error was generated for warning 'Microsoft.EntityFrameworkCore.Infrastructure.DetachedLazyLoadingWarning': An attempt was made to lazy-load navigation 'CalendarRuleConditions' on a detached entity of type 'CalendarRuleProxy'. Lazy-loading is not supported for detached entities or entities that are loaded with 'AsNoTracking'. This exception can be suppressed or logged by passing event ID 'CoreEventId.DetachedLazyLoadingWarning' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'.

Похоже, что данные, содержащиеся в «CalendarRule.CalendarRuleConditions», не были загружены. Я не использую «AsNoTracking», и перед кодом API, который я опубликовал, не вызывается SaveChangesAsync(). Как я могу решить проблему?

Какова реализация MemberwiseClone()? Если он создает другой прокси-сервер отложенной загрузки вместо CalendarRule, это может объяснить ошибку. У вас включена ленивая загрузка?

David Browne - Microsoft 16.03.2022 16:38
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
48
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Этот вопрос похож на этот другой.

Я думаю, что проблема в (CalendarRule)MemberwiseClone(), вы должны создать сущность с Create (ef) или CreateProxy (efcore) вместо new.

Ответ принят как подходящий

Этот код здесь не имеет никакого смысла:

foreach (CalendarRuleCondition condition in clonedRule.CalendarRuleConditions)
{
    conditions.Add((CalendarRuleCondition)condition.Clone());
}

clonedRule.CalendarRuleConditions = conditions;

Если вы вызываете этот метод Clone() из экземпляра объекта, который хотите клонировать, это должно быть:

foreach (CalendarRuleCondition condition in CalendarRuleConditions)
{
    conditions.Add((CalendarRuleCondition)condition.Clone());
}

clonedRule.CalendarRuleConditions = conditions;

Где мы проходим через каждое условие в лениво загруженных CalendarRuleConditions этого объекта, чтобы создать клонированный список для клона. Даже в этом случае было бы лучше загрузить CalendarRuleConditions и полагаться только на ленивую загрузку в качестве запасного варианта.

Спасибо, с этим решением я устранил ошибку!

Lorenzo Lanzarone 18.03.2022 14:59

Другие вопросы по теме