Willy
Willy

Reputation: 10648

EF 4.1 Issue retrieving original and current values

I am using EF 4.1 and lazy loading. I have below entities:

public abstract class PersonBase
{
   [Key(), Required]
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public int Id { get; set; }

   ....
   [ForeignKey("Quantity")]
   public virtual int? QuantityId { get; set; }
   public virtual Quantity Quantity { get; set; }
   ....
}

public class ConcretePerson : PersonBase
{
  ....
}

public class Quantity
{
    [Key(), Required]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required]
    public virtual float QuantityA { get; set; }

    [Required]
    public virtual float QuantityB { get; set; }

    [Required]
    public virtual float QuantityC { get; set; }
}

IDbSet<Quantity> Quantities;
IDbSet<ConcretePerson> ConcretePersons;
IDbSet<PersonBase> Persons;

so in my code I perform below:

using (DataBaseContext context = new DataBaseContext())
{
    IQueryable<ConcretePerson> concretePersonCollection = context.ConcretePersons.Where(<condition>);
    foreach (ConcretePerson concretePerson in concretePersonCollection)
    {
        ...
        concretePerson.Quantity.QuantityA = new_quantity_A;
        concretePerson.Quantity.QuantityB = new_quantity_B;
        concretePerson.Quantity.QuantityC = new_quantity_C;
        ...
    }

    ...

    DbEntityEntry<ConcretePerson> entityEntry;
    Quantity quantity;
    foreach (ConcretePerson concretePerson in concretePersonCollection)
    {
       entityEntry = context.Entry<ConcretePerson>(concretePerson);
       if (entityEntry.State == System.Data.EntityState.Modified)
       {
           quantity = ((ConcretePerson)entityEntry.CurrentValues.ToObject()).Quantity;
       }
       else
       {
           quantity = concretePerson.Quantity;
       }

       ...
    }   

    ...

    context.SaveChanges();
}


Note that I only perform SaveChanges at the end so database is not updated until this point is reached.

I have problems within the second foreach:
1.- When entityEntry.State is modified it happens that ((ConcretePerson)entityEntry.CurrentValues.ToObject()).Quantity is null but ((ConcretePerson)entityEntry.CurrentValues.ToObject()).QuantityId is correct (contains the correct value) Why? How to get this different from null with the current values (neither original values nor database values), just current values?

2.- If I check directly the Quantity by performing concretePerson.Quantity it is not null but concretePerson.Quantity contains the current values (the ones updated in the first foreach), not the original ones (the values before updating in the first foreach). Should not concretePerson.Quantity contain the original values (before updating in the first foreach) instead? because I have not performed any context.savechanges between the two foreach loops.
3.-Context.SaveChanges is not saving the changes done to the database and is not raising any error. <---- This point is solved, I was pointing to a different context, no using the same (now I am using the same).

Upvotes: 1

Views: 531

Answers (1)

Dave Williams
Dave Williams

Reputation: 2246

  1. That is an odd way of trying to get values... try this.

  2. concretePerson.Quantity will be the local copy of the entity so it will have whichever value you assigned to it.

In the first foreach you are actually modifying each of the items in the collection (even if it is not saved to the database yet it is still in memory, otherwise how would EF know what to save to the database?).

In the second you are actually checking the same collection to see if entities have been modified (which they have) and then getting the current value. However the current value for quantity will be the same as .quantity because you have modified the entity. If you check the original value for modified entries you will see that it is different.

Basically CurrentValue is the value of the in memory entity (if you change the property CurrentValue changes). OriginalValue is "usually the entity's property values as they were when last queried from the database"

  1. Nevermind ;p

Upvotes: 1

Related Questions