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
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);
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; }
}
In Entity Framework Core using Code First, I got this to work by doing two things:
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
decorator to the Entity's Primary Key, like Yashveer Singh's answer statedAfter 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();
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);
}