I have an MVC application that uses Entity Framework 5. In several places, I have code that creates or updates entities, and then needs to perform some operations on the updated data. Some of these operations require access to the navigation properties, and I cannot update them.
Here is an example (simplified code that I have)
Models
class User : Model { public Guid Id { get; set; } public string Name { get; set; } } class Car : Model { public Guid Id { get; set; } public Guid DriverId { get; set; } public virtual User Driver { get; set; } [NotMapped] public string DriverName { get { return this.Driver.Name; } } }
controller
public CarController { public Create() { return this.View(); } [HttpPost] public Create(Car car) { if (this.ModelState.IsValid) { this.Context.Cars.Create(booking); this.Context.SaveChanges();
The above example is for the Create method, but I also have the same problem with the Update method, which is very similar in that it simply takes an object from the context into the GET action and saves it using the Update method in the POST action.
public virtual void Create(TObject obj) { return this.DbSet.Add(obj); } public virtual void Update(TObject obj) { var currentEntry = this.DbSet.Find(obj.Id); this.Context.Entry(currentEntry).CurrentValues.SetValues(obj); currentEntry.LastModifiedDate = DateTime.Now; }
Now I tried several different approaches that I searched or found on the stack, but nothing works for me.
In my last attempt, I tried to unload the reboot after calling the SaveChanges method and requesting data from the database. Here is what I did.
I overlaid the SaveChanges method to update the context of the object immediately after saving
public int SaveChanges() { var rowsNumber = this.Context.SaveChanges(); var objectContext = ((IObjectContextAdapter)this.Context).ObjectContext; objectContext.Refresh(RefreshMode.StoreWins, this.Context.Bookings); return rowsNumber; }
I tried to get updated object data by adding this line of code right after calling SaveChanges in my HTTP Create and Update actions:
car = this.Context.Cars.Find(car.Id);
Unfortunately, the navigation property is still null . How can I correctly update the DbContext immediately after changing the data?
EDIT
I forgot to mention initially that I know a workaround, but it's ugly and I don't like it. Whenever I use the navigation property, I can check if it is null , and if that is, I can manually create a new DbContext and update the data. But I would really like to avoid such hacks.
class Car : Model { [NotMapped] public string DriverName { get { if (this.Driver == null) { using (var context = new DbContext()) { this.Driver = this.context.Users.Find(this.DriverId); } } return this.Driver.Name; } } }