2

I am integrating my windows application with nopcommerce. So In that when I register the customer from nopcommerce then all the info should be saved to new table Customer of my windows app. for that I created trigger after insert on Table GenericAttribute.

But when I am going to register customer then error occurs in following schema at EfRepository.cs:

protected string GetFullErrorTextAndRollbackEntityChanges(DbUpdateException exception)
{
    //rollback entity changes
    if (_context is DbContext dbContext)
    {
        var entries = dbContext.ChangeTracker.Entries()
            .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified).ToList();

        entries.ForEach(entry => entry.State = EntityState.Unchanged); //here error occurs
    }

    _context.SaveChanges();
    return exception.ToString();
}

and the Error is :

InvalidOperationException: The property 'Id' on entity type 'GenericAttribute' has a temporary value while attempting to change the entity's state to 'Unchanged'. Either set a permanent value explicitly or ensure that the database is configured to generate values for this property

trashr0x
  • 6,457
  • 2
  • 29
  • 39
Tejas
  • 381
  • 1
  • 7
  • 25
  • I suspect the issue is that you're taking added and modified entities together, and trying to revert changes. As you haven't committed the newly added entries to the database yet, calling `EntityState.Unchanged` on it makes the context think that it should already exist, but validation is failing because `Id` doesn't have a value. I'd remove any newly created entities. – Barry O'Kane Aug 29 '18 at 09:49

1 Answers1

0

I got the same exception when I had unique index, AddRange failed on unique index and then inside the catch exception block was try to remove whole inserted collection. (Not my code, but I had to fix it :-) )

Code sample (simplified):

try {
    context.AddRange(users); // List<User>, has property List<Contact>
    context.SaveChanges(); // throws exception on unique index
} catch (Exception ex) {
    context.RemoveRange(users); // this throws exception "The property 'UserID' on entity type 'Contact' has a temporary value"
    throw;
}

I think that you're trying to do the same thing (internally) different way. Just use transactions instead of hacking EF.

Tomino
  • 5,969
  • 6
  • 38
  • 50