Я использую 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(). Как я могу решить проблему?
Этот вопрос похож на этот другой.
Я думаю, что проблема в (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 и полагаться только на ленивую загрузку в качестве запасного варианта.
Спасибо, с этим решением я устранил ошибку!
Какова реализация
MemberwiseClone()
? Если он создает другой прокси-сервер отложенной загрузки вместо CalendarRule, это может объяснить ошибку. У вас включена ленивая загрузка?