无法使用 Entity Framework 中的 AddRange 自动生成 IDENTITY

Can't auto-generate IDENTITY with AddRange in Entity Framework

我不知道这是 Entity Framework 的设计选择还是代表我的错误方法,但每当我尝试将 AddRange 实体添加到 DbSet 时,我似乎无法获得自动 -生成的 IDENTITY 字段。

[Table("entities")]
public class Entity 
{
    [Key]
    [Column("id")]
    public long Id { get; set; }

    [Column("field")]
    public string Field { get; set; }
}

var entities = new Entity[] 
{
    new Entity() { Field = "A" },
    new Entity() { Field = "B" },
};

_dbContext.Entities.AddRange(entities);
await _dbContext.SaveChangesAsync();

//ids are still default(long) at this point!!

编辑: 这是显示导致问题的原因的更新代码:可枚举。无需为实体添加其他属性 类.

public class Request
{
    public string Field { get; set; }

    public Entity ToEntity()
    {
        return new Entity() { Field = Field };
    }
}

public async Task<IEnumerable<long>> SaveRequests(IEnumerable<Request> requests)
{
    var entities = requests.Select(r => r.ToEntity()); //not working
    var entities = requests.Select(r => r.ToEntity()).ToArray(); //working

    _dbContext.Entities.AddRange(entities);
    await _dbContext.SaveChangesAsync();

    return entities.Select(e => e.Id);
}

请试试这个,它适用于 Int 类型列,需要在 long 类型上尝试。

[Table("entities")]
public class Entity 
{
    [Key]
    [Column("id")]
    // this you need to tell to Ef to use Identity .
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long Id { get; set; }

    [Column("field")]
    public string Field { get; set; }
}

我在 EF 6 中使用数据库优先,在尝试了一段时间后,我找到了一个可能的解决方案。

首先,检查数据库中的 Table,确保将 'ID' 列定义为自增主键字段,可以使用类似

ID int IDENTITY(1,1) PRIMARY KEY,

创建您的 table 时。一些相关资料可以看here1 or here2.

或者您可以在 MSSQL IDE 中检查数据属性,例如:

其次,将'ID'列的StoreGeneratedPattern设置为Identity,你可以通过在Visual Studio,右击table和select属性中的Data Column,StoreGeneratedPattern设置在属性Window:

部分相关文章见here

完成上述操作后,使用 EF AddRange,ID 将自动递增,一切正常。

public class Entity 
{
    public long Id { get; set; }
    public string Field { get; set; }
}

var entities = new Entity[] 
{
    new Entity() { Field = "A" },
    new Entity() { Field = "B" },
};

_dbContext.Entities.AddRange(entities);

是什么导致了这个问题?可枚举!查看我问题中的 EDIT 部分以获取解决方案。

编辑: 在此处发布更新的代码作为答案。问题在于我使用枚举的方式。底线是,当您需要立即获得一致的结果时,永远不要相信延迟加载。

public class Request
{
    public string Field { get; set; }

    public Entity ToEntity()
    {
        return new Entity() { Field = Field };
    }
}

public async Task<IEnumerable<long>> SaveRequests(IEnumerable<Request> requests)
{
    var entities = requests.Select(r => r.ToEntity()); //not working
    var entities = requests.Select(r => r.ToEntity()).ToArray(); //working

    _dbContext.Entities.AddRange(entities);
    await _dbContext.SaveChangesAsync();

    return entities.Select(e => e.Id);
}

在 Entity Framework Core using Code First 中,我通过做两件事让它工作:

  1. 我将 [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 装饰器添加到实体的主键,如 Yashveer Singh 的回答所述
  2. 我将新实体对象的主键设置为 0

执行这两个步骤后,我不需要将 IEnum 转换为数组。我只是能够 运行:

_dbContext.Entities.AddRange(entities);
await _dbContext.SaveChangesAsync();