Функция EF Core Add возвращает отрицательный идентификатор

Сегодня я заметил странную вещь, когда пытался сохранить сущность и вернуть ее идентификатор в EF Core.

До: Идентификатор равен 0, прежде чем он был добавлен в базу данных После: Теперь идентификатор был изменен на отрицательное значение

Я думал о том, было ли это до вызова saveChanges(), но он работает с другим объектом с аналогичной настройкой.

PS: Я использую единицу работы, чтобы сохранить все изменения в конце.

В чем была причина?

1 ответ

Решение

Он будет отрицательным, пока вы не сохраните свои изменения. Просто позвони Save в контексте.

_dbContext.Locations.Add(location);
_dbContext.Save();

После сохранения у вас будет идентификатор, который находится в базе данных. Вы можете использовать транзакции, которые можно откатить в случае возникновения проблемы после получения идентификатора.

Другой способ - не использовать встроенные поля базы данных IDENTITY, а реализовать их самостоятельно. Это может быть очень полезно, когда у вас много операций массовой вставки, но это идет с ценой - это нелегко реализовать.

Видимо, это не ошибка, это особенность: https://github.com/aspnet/EntityFrameworkCore/issues/6147

Не слишком сложно переопределить это поведение следующим образом:

 public class IntValueGenerator : TemporaryNumberValueGenerator<int>
 {
     private int _current = 0;

     public override int Next(EntityEntry entry)
     {
         return Interlocked.Increment(ref _current);
     }    
 }

Затем обратитесь к генератору пользовательских значений здесь:

public class CustomContext: DbContext
{
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        foreach (var type in modelBuilder.Model.GetEntityTypes().Select(c => c.ClrType))
        {
            modelBuilder.Entity(type, b =>
            {              
                b.Property("Id").HasValueGenerator<IntValueGenerator>();
            });
        }
        base.OnModelCreating(modelBuilder);
    }
}

Это приведет к увеличению временного идентификатора с "1", однако требуется больше усилий для предотвращения конфликтов ключей при попытке сохранения.

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