1

I am trying to update a database entry using entity framework. The entities are as follows:

public partial class Test
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid identity { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public TestRef Colour { get; set; }
}

public class TestRef
{
    public int id { get; set; }
    public string favColor { get; set; }
}

and the edit ActionResult in the relevant Controller is as follows:

public ActionResult Edit([Bind(Include = "identity,Name,Age,Colour")] Test test)
{
    if (ModelState.IsValid)
    {
        test.Colour = db.TestRefs.Find(test.Colour.id);
        db.Tests.Attach(test);
        db.Entry(test).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(test);
}

So here, Edit seems to work for all the properties in Test except for Colour (in that all the other properties get updated, but Colour remains as it was before, with no change). I am assuming this is because it is an association, but I can't for the life of me figure out why.

lorond
  • 3,856
  • 2
  • 37
  • 52
  • You need to be more specific about what is not working. Is the Colour property binding correctly on the request? Is the Colour property not being set in the database? Does the TestRef you are trying to link this Test to exist in the database already? Give us details please. – Jakotheshadows Jul 08 '16 at 16:03
  • The Colour property is binding, but not being set in the Database. Also the TestRefs do already exist in the Database. – ASMoncrieff Jul 08 '16 at 16:21

1 Answers1

3

First, tell EF that TestRef have a key:

public class TestRef
{
    [Key] /* <--- */
    /*[DatabaseGenerated( ??? )] Does value generated by database? */
    public int id { get; set; }
    public string favColor { get; set; }
}

Second, make reference be a foreign key:

public partial class Test
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid identity { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }

    [ForeignKey("TestRefID")]  /* <--- */
    public TestRef Colour { get; set; }
}

Name TestRefID in code above is just example. Put there name of FK column from your database. You do have FK column in database for this relation, isn't it?

Also, if you need lazy loading, make Colour property virtual:

...
    [ForeignKey("TestRefID")]
    public virtual TestRef Colour { get; set; }
...

EF will make a direved type and for all virtual reference properties it will implement lazy-loading logic. It's default behavior until you disable it in db context settings:

yourDataContext.ContextOptions.LazyLoadingEnabled = false;

By the way, it's not a good idea to use GUID as primary key. Look here for cons and pros.

lorond
  • 3,856
  • 2
  • 37
  • 52