Как использовать «SaveChanges» после обновления EF Core 2.1 до 3.1 - PullRequest
0 голосов
/ 21 апреля 2020
  • Я обнаружил, что поведение "SaveChanges" было изменено после обновления EFCore с 2.1 до 3.1:
  • Не удалось правильно установить внешний ключ для формирования связей между объектами в сценарий создания, и, похоже, он связан с этим критическим изменением . ** «Временные значения ключей больше не устанавливаются на экземпляры сущностей» **
  • Вот фрагмент кода my, он просто создает новую сущность A и сущность B, которые имеют отношение один ко многим между A и B, B имеет свойство навигации «A_Id» и объявление ограничения БД в классе AutoMapp.
public class A
{
    public long Id { get; set; }
}

public class B
{
    public long a_Id { get;set; }
    public A a { get;set; }
}

public class BMap
{
    builder.HasForeignKey(x => x.A_Id)
           .HasConstraintName("FK_dbo.B_dbo.A_AId");
}

using (var context = _contextFactory.Create())
{
    A a;
    if (aDto.IsTransient)
    {
        a = context.AttachAsAdded<ADto>(aDto);
    }
    //await context.SaveChangesAsync();
    foreach (var bId in aDto.bIds)
    {
        context.AttachAsAdded(new B { a_Id = a.Id });
    }
    await context.SaveChangesAsync();
}

public TEntity AttachAsAdded<TEntity>(SimpleEntity dto)
            where TEntity : Entity, new()
        {
            var autoDetectChangesEnabled = ChangeTracker.AutoDetectChangesEnabled;
            ChangeTracker.AutoDetectChangesEnabled = false;

            var entity = new TEntity();
            var entry = Entry(entity);
            entry.CurrentValues.SetValues(dto);
            entry.State = EntityState.Added;

            ChangeTracker.AutoDetectChangesEnabled = autoDetectChangesEnabled;
            return entity;
        }

  • Фактически, EFCore попытается выполнить SQL с присвоением внешнего ключа (a_Id) в качестве начального значения a.Id, который является отрицательным числом.
  • И в моем случае возникает исключение:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.B_dbo.A_AId". The conflict occurred in database "XXXX", table "dbo.A", column 'Id'. The statement has been terminated.”
  • В качестве обходного пути я решил эту проблему, выполнив «SaveChangeAsyn c» перед использованием значение, которое генерируется БД. (прокомментированная строка выше)

  • Пожалуйста, помогите мне, если есть какой-либо другой способ решить эту проблему. Большое спасибо.

...