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

后端 未结 4 1522

I don\'t know if it\'s an Entity Framework\'s desing choice or a wrong approach on my behalf, but whenever I try to AddRange entities to a DbSet I can\'t seem to get the aut

相关标签:
4条回答
  • 2021-01-07 22:07

    I'm using Database First in EF 6, and after trying for a period of time, I find a possible solution.

    First, Check your Table in the Database, Ensure that you defined the 'ID' column as an auto-increment primary key field, which can be declared by using something like

    ID int IDENTITY(1,1) PRIMARY KEY,
    

    when creating your table. Some related information can see here1 or here2.

    or you can check the data Properties in MSSQL IDE like:

    Second, Set the 'ID' column's StoreGeneratedPattern as Identity, you can do it by open the edmx file in Visual Studio, right click on the Data Column in table and select Properties, and StoreGeneratedPattern setting is in the Properties Window :

    Some related article see here.

    After complete things above, using EF AddRange, ID will auto increment and all works great.

    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);
    
    0 讨论(0)
  • 2021-01-07 22:15

    Please try this, it works for Int type column, need to try on long types.

    [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; }
    }
    
    0 讨论(0)
  • 2021-01-07 22:17

    In Entity Framework Core using Code First, I got this to work by doing two things:

    1. I added the [DatabaseGenerated(DatabaseGeneratedOption.Identity)] decorator to the Entity's Primary Key, like Yashveer Singh's answer stated
    2. I set the new entity object's primary key to 0

    After performing those two steps, I didn't need to convert IEnums to Arrays. I was simply able to run:

    _dbContext.Entities.AddRange(entities);
    await _dbContext.SaveChangesAsync();
    
    0 讨论(0)
  • 2021-01-07 22:18

    What was causing the problem? Enumerables! Take a look at the EDIT section in my question for the solution.

    EDIT: posting the updated code here as answer. The problem was in the way I used enumerables. Bottom line is you should never trust lazy loading when you need consistent results right away.

    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);
    }
    
    0 讨论(0)
提交回复
热议问题