当IDENTITY设置为OFF时,以编程方式获取主键的下一个值

时间:2014-03-25 08:46:48

标签: c# asp.net-mvc-5 entity-framework-6

我的表主键设置为[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]

我想将记录复制到带有新主键的新行中,除了获取最大值并添加1

之外,还有最佳方法吗?

3 个答案:

答案 0 :(得分:3)

我建议将 IDENTITY设置为On以获得电池可维护性。但如果你不能发送它,那么有两个建议:

<强> 1。将数据类型设置为UniqueIdentifier:

您可以将主键的数据类型设置为UniqueIdentifier,并从后面的代码中为主键分配值,如下所述:

var newId = Guid.NewGuid();

<强> 2。插入前获取最大ID:

如果UniqueIdentifier不是解决方案,则从主键获取最大值,并将最大值+ 1 设置为下一个ID,如下所述:

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

答案 1 :(得分:0)

您可以做的是尝试让您的密钥尽可能独特。这是一种具有sql唯一标识符的想法。可能使用日期时间或类似的时间。

我仍然认为这是一个黑客,应该是最后的手段。

答案 2 :(得分:0)

我有类似的问题,但我不需要第二个id字段。我的主要ID已经是一个guid,但客户端需要一个数字字段,以便contactId显示在应用程序中。似乎工作得很好因为我们不删除任何实体只是将它们标记为isActive = false所以不用担心重复数字。

基本实体类

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标记为正确的答案感谢您的建议对我有用...