Программно получить следующее значение для первичного ключа, если для параметра IDENTITY установлено значение OFF

asp.net-mvc-5 c# entity-framework-6

Вопрос

Первичным ключом моей таблицы установлено значение [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]

Я хочу скопировать записи в новую строку с новым первичным ключом, есть ли лучший способ сделать это, кроме принятия максимального значения и добавления 1

Принятый ответ

Я бы предложил установить IDENTITY в On для обеспечения работоспособности теста . Но если вы не можете его отправить, есть два предложения:

1. Задайте тип данных как UniqueIdentifier:

Вы можете установить тип данных вашего первичного ключа на UniqueIdentifier и присвоить значение первичному ключу из кода позади, как указано ниже:

var newId = Guid.NewGuid();

2. Получите Max ID перед вставкой:

Если UniqueIdentifier не является решением, тогда получите максимальное значение из вашего первичного ключа и установите Max Value + 1 в качестве следующего идентификатора, как указано ниже:

var maxId = this.DataContext.[TableName].Max(table => table.[PK_Column]);
var newId = maxId + 1;

Популярные ответы

У меня была аналогичная проблема, но мне не понадобилось второе поле id. Мой первичный идентификатор был уже ориентиром, но клиент хотел, чтобы контактное имя отображалось в приложении. Кажется, отлично работает, потому что мы не удаляем никаких объектов, просто отмечаем их как isActive = false, поэтому не боимся повторения чисел.

Базовый класс Entity

public virtual void PrepareSave(EntityState state)
{
    var identityName = Thread.CurrentPrincipal.Identity.Name;
    var now = DateTime.UtcNow;

    if (state == EntityState.Added)
    {
        CreateBy = identityName ?? "unknown";
        CreateDate = now;
    }

    LastModifedBy = identityName ?? "unknown";
    LastModifed = now;
}

Я добавил это к единственному объекту, которому это требование необходимо

public override void PrepareSave(EntityState state)
{
    var context = new DbContext();
    var maxId = context.Contacts.Max(model => model.ContactId);
    ContactId = maxId + 1;
    context.Dispose();

    var identityName = Thread.CurrentPrincipal.Identity.Name;
    var now = DateTime.UtcNow;

    if (state == EntityState.Added)
    {
        CreateBy = identityName ?? "unknown";
        CreateDate = now;
    }

    LastModifedBy = identityName ?? "unknown";
    LastModifed = now;
}

В Datacontext я также добавил это

public override async Task<int> SaveChangesAsync()
    {
        var modifiedEntries = ChangeTracker.Entries()
            .Where(x => x.State == EntityState.Added || x.State == EntityState.Modified);

        foreach (var entry in modifiedEntries)
        {
            // try and convert to an Auditable Entity
            var entity = entry.Entity as BaseEntity;
            // call PrepareSave on the entity, telling it the state it is in
            entity?.PrepareSave(entry.State);
        }

        var result = await base.SaveChangesAsync();
        return result;
    }

Это было основано на ответе, отмеченном как правильно выше SpiderCode. Спасибо, что предложение отлично поработало для меня ...




Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему