I'm trying to update a virtual property using EF6 and MVC. My code goes like this:
public async Task<ActionResult> Edit([Bind(Include = "Id,Title,Content,Image")] Recommendation recommendation, HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
if (file != null)
{
//we have an image - saving it to db
var image = Server.SaveFile(file, Request);
DB.Files.Add(image);
await DB.SaveChangesAsync();
//assign the new image to the recommendation
recommendation.Image = image;
}
recommendation.User = await GetLoggedInUserAsync();
DB.Entry(recommendation).State = EntityState.Modified;
await DB.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(recommendation);
}
The image is saved in the Files
table. Yet the Image_Id
column in Recommendations
table won't update to the new Image_Id
. What am I missing here?
Classes:
public class Item
{
[Key]
public int Id { get; set; }
public virtual ApplicationUser User{ get; set; }
[Required]
[DataType(DataType.Text)]
[Display(Name = "Title")]
public string Title { get; set; }
[Required]
[DataType(DataType.MultilineText)]
[Display(Name = "Content")]
public string Content { get; set; }
}
public class Recommendation : Item
{
[DisplayName("Image")]
public virtual File Image { get; set; }
}
public class File
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Url { get; set; }
}
The problem is, you are working with independent association (which has no foreign key ID), like.
public int ImageId { get; set; }
And you also works with disconnected object. So you need to maintain the relationship manually. You also have to delete the old relationship first before adding new relationship.
If you are working with disconnected objects you must manually manage the synchronization. - MSDN
Try adding this code to manually manage the relationship.
var manager = ((IObjectContextAdapter)DB).ObjectContext.ObjectStateManager;
// Removes previous relationship.
if (recommendation.Image != null)
{
// If there is another image, but you don't remove it, the update will fail.
manager.ChangeRelationshipState(recommendation, recommendation.Image,
r => r.Image, EntityState.Deleted);
}
// Adds new relationship.
manager.ChangeRelationshipState(recommendation, image,
r => r.Image, EntityState.Added);
Try to reconsider the class design to have the foreign key association.
See this post for more information.