I am using EF Core 1.1.1
. I have noticed when i add IEnumerable<Entity>
using AddRange
method and then call SaveChanges()
then entities gets saved in the database however their ID does not get refreshed.
Code below does not refresh ID after SaveChanges(). Note i am passing requests as IEnumerable
public async Task Post([FromBody]IEnumerable<string> values)
{
var requests = values.Select(x => new Test()
{
Name = x,
Status = "Init"
});
await _dbContext.Tests.AddRangeAsync(requests).ConfigureAwait(false);
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
foreach (var r in requests)
{
var id = r.ID;
}
}
Code below does not refresh ID after SaveChanges(). Note i am passing request.ToList()
as a parameter to AddRange
method
public async Task Post([FromBody]IEnumerable<string> values)
{
var requests = values.Select(x => new Test()
{
Name = x,
Status = "Init"
});
await _dbContext.Tests.AddRangeAsync(requests.ToList()).ConfigureAwait(false);
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
foreach (var r in requests)
{
var id = r.ID;
}
}
Code below does refresh ID after SaveChanges(). Note I am calling ToList()
after selecting values.
public async Task Post([FromBody]IEnumerable<string> values)
{
var requests = values.Select(x => new Test()
{
Name = x,
Status = "Init"
}).ToList(); //<------ ToList() or ToArray() would work
await _dbContext.Tests.AddRangeAsync(requests).ConfigureAwait(false);
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
foreach (var r in requests)
{
var id = r.ID;
}
}
I am not sure if this is a bug in EF or this is how it supposed to work. I understand IEnumerable
is lazy
and List
and Array
are eager
, but if AddRange
method is taking IEnumerable
as parameter then it should work regardless.
As Ivan states the reason you are not seeing the id's is that in the Non working cases you are enumerating new test objects.
If you place a break point inside the enumerable you will see that during your for each it creates new Test objects at that time. These are NOT the same objects that were place in the database.
You are actually enumerating the IEnumerable twice
public async Task Post([FromBody]IEnumerable<string> values)
{
var requests = values.Select(x => {
//place break point here
new Test()
{
Name = x,
Status = "Init"
}
});
await _dbContext.Tests.AddRangeAsync(requests.ToList()).ConfigureAwait (false);
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
foreach (var r in requests)
{
var id = r.ID;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With