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 auto-generated IDENTITY fields.
[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!!
EDIT:
Here's the updated code to show what was causing the problem: enumerables. No need to add other attributes to the entity classes.
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);
}
What was causing the problem? Enumerables! Take a look at the EDIT section in my question for the solution.
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; }
}