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.

2
  • 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. Commented Jul 8, 2016 at 16:03
  • The Colour property is binding, but not being set in the Database. Also the TestRefs do already exist in the Database. Commented Jul 8, 2016 at 16:21

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for this, I'll try it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.