Daniel Santos
Daniel Santos

Reputation: 15778

ASP.Net MVC. How automatically persist relational data using Entity Framework?

This are POCO Code First Classes:

class Contact{
    [Key]
    public int Id {get; set;}
    public string name {get; set;}
    public ICollection<Phone> phones{get; set;}
}

class Phone{
    [Key]
    public int id {get;set;}
    public string phone_type {get; set;}
    public string phone_number {get; set;}
    public Contact contact { get; set; }
}

I would like to persist it on DB.

This is the controller:

the binded "contact" instance does contains a Contact with a List phones with a lot of phones.

public ActionResult Edit([Bind()] Contact contact) {
    if (ModelState.IsValid)
    {
        db.Entry(contact).State = System.Data.Entity.EntityState.Modified;
        db.SaveChangesAsync();
        return RedirectToAction("Index");
    }
    return View(contact);
}

But this code only persist the Contact instance on db. The Phones table still empty.

Is there any configuration to automatically persist the related "phones" data on the db, Or must it be coded by hand?

for those interested, the view is like this (simplified):

@model SGD.Models.Contact
Name:    @Html.EditorFor(model => model.name)
Phones: <div id="phones"></div>

where the #phones div is populated with this partial with a incremental index.

<input name="phones[@index].id" type="hidden" />
<input name="phones[@index].phone_type" />
<input name="phones[@index].phone_number" />

Upvotes: 2

Views: 92

Answers (1)

ocuenca
ocuenca

Reputation: 39326

Now I was reading if you just change the State to Modified in the root entity, the related entities don't change their states (reference):

Note that if the entity being attached has references to other entities that are not yet tracked, then these new entities will attached to the context in the Unchanged state—they will not automatically be made Modified. If you have multiple entities that need to be marked Modified you should set the state for each of these entities individually.

Try using TryUpdateModel. I'm not totally sure if it update related entities, but it should if your model binds the related entity.

var contact= db.Contacts.Include(c=>c.Addresses).FirstOrDefault(c=>c.Id==contact.Id);
TryUpdateModel(contact);

What I always use in this cases is a ViewModel and I map it later to one of my entities using Automapper

Also there is a 3rd party library (GraphDiff) that allow you to save an entire detached Model/Entity, with child Entities and Lists, to the database without writing the code to do it.

Upvotes: 1

Related Questions