OriginalValues cannot be used for entities in the Added state

c# entity-framework

Question

I am using Entity Framework to build an web application, the database is created on startup and my seed method adds some entities to the database without any problem. Also the retrieve of the entities is working without problems.

My problem is that if I try to create an entity from my UI layer, I come across the error OriginalValues cannot be used for entities in the Added state. The exception is not thrown to the UI, but I found it when I digged around from the problem.

I happens in my:

public virtual TEntity Add(TEntity entity)
{
    var entry = _context.Entry(entity);
    entry.State = EntityState.Added;
    _dbSet.Add(entity);

    return entity;
}

Screenshot:

enter image description here

The entity is very small and the mappings:

public abstract class EntityBase
{
    public int Id { get; set; }
}

public class AccessCode : EntityBase
{
    public string Code { get; set; }
    public int UsageCount { get; set; }
}

public class AccessCodeMapping : EntityTypeConfiguration<AccessCode>
{
    public AccessCodeMapping()
    {
        // Table
        ToTable("AccessCode");

        // Primary key
        HasKey(x => x.Id);

        // Properties
        Property(accesscode => accesscode.Code).IsRequired().HasMaxLength(256);
        Property(accesscode => accesscode.UsageCount).IsRequired();
    }
}

And this is how I create a test access code for demo purpose

var ac = new AccessCode {Code = "321", UsageCount = 0};
_accessCodeService.Create(ac);
_unitOfWork.Save();
return View("Login");

Can anyone figure out why this error is occurring? I'm lost. :-)

P.s Let me know if there is some pieces of code you wish to see.

1
42
3/15/2014 9:40:13 AM

Accepted Answer

When EF retrieves an entity from the database it takes a snapshot of the original values for all properties of that entity. Later, as changes are made to the values of these properties the original values will remain the same while the current values change.

However, for this to happen EF needs to be tracking the entity throughout the process. In a web or other n-tier application, typically the values are sent to the client and the context used to query the entity is disposed. This means that the entity is now no longer being tracked by EF. This is fine and good practice.

Once the application posts back the entity is reconstructed using values from the client and then re-attached to the context and set into a Modified state. However, by default the only values that come back from the client are the current values. The original values are lost. Usually this doesn't matter unless you are doing optimistic concurrency or want to be very careful about only updating values that have really changed. In these cases the original values should also be sent to the client (usually as hidden fields in a web app) and then re-applied as the original values as a part of the attach process. This was not happening in the example above and this is why the original values were not showing as expected.

15
2/28/2014 9:33:00 AM

Popular Answer

If you change

dbEntry.OriginalValues.GetValue<object>(propertyName);

to

dbEntry.GetDatabaseValues().GetValue<object>(propertyName);

then that works.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow