pQuestions123 pQuestions123 - 2 months ago 15
C# Question

Strange Entity Framework behavior - Adds double when IEnumerable is not List

I have a Repository base class which has the following method:

public void AddRange(IEnumerable<TEntity> entities)
{
Context.Set<TEntity>().AddRange(entities);
foreach (var entity in entities)
{
if (Context.Entry(entity).State == EntityState.Detached)
{
Context.Entry(entity).State = EntityState.Added;
}
}
}


I call it like so:

uow.UserPermissions.AddRange(permissions);


where UserPermissions is a repository that inherits from the base.

I am seeing some strange behavior that I cannot explain when permissions is not a list. For example when I try something like this:

var permissions = permissionDtos.Select(dto => new UserPermission()
{
...
});

uow.UserPermissions.AddRange(permissions);


entity framework adds twice as many permissions to the db as there are permissionDtos. However, if I add a ToList() at the end of the select statement, the strange behavior goes away. I also noticed that when I comment out the forEach loop (that modifies the context entries state) in the Repository.AddRange() method, the strange behavior goes away as well (even without adding the ToList()).

Thanks in advance.

Answer

You're doing it wrong.That is why this behaviour.When you do this Context.Set<TEntity>().AddRange(entities);,it Adds the given collection of entities into context underlying the set with each entity being put into the Added state such that it will be inserted into the database when SaveChanges is called.You can see it on MSDN. So you don't need to do it again inside the foreach loop.When you remove either one, your method should be OK.

You can try as shown below.

public void AddRange(IEnumerable<TEntity> entities)
        {
            Context.Set<TEntity>().AddRange(entities);

        }