Parent-Child Update

Posts   
 
    
oq
User
Posts: 6
Joined: 17-Jun-2009
# Posted on: 15-Jul-2009 04:31:32   

I can't seem to find something similar to this problem I'm having so I'll explain where my struggle lies.

I have a parent-child relationship. I'm using the Self Servicing model. I want to make updates to the parent and the child entities. In order to update the parent, I create a new parent entity using an existing primary key. I also set parent.IsNew = false. If I modify parent fields and save the entity, the proper record is updated. My problem lies with the child collection.

What is the easiest way to update a child of the parent instance I've defined above, such that when I call the parent's save method ( recurse = true), the children are updated?

I can't get the update to work. When I execute save I always seem to be inserting child records instead of updating existing ones.

Thanks!

Rudy

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 15-Jul-2009 05:16:43   

Hi Rudy,

As I see that you are using IsNew = false; I guess you want to avoid the fetch of the entity, isn't?

Please show the code snippet where you are doing such thing, to see what is the problem.

David Elizondo | LLBLGen Support Team
oq
User
Posts: 6
Joined: 17-Jun-2009
# Posted on: 15-Jul-2009 05:31:44   

The code is setup through an ASP.NET MVC Post through the controller. The controller method handling the post is:


        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(
            [Bind(Prefix = "agent")] AgentEntity agent,
            [Bind(Prefix = "address")] AddressEntity address,
            [Bind(Prefix = "personAddress")] PersonAddressEntity personAddress,
            [Bind(Prefix = "email")] EmailEntity email,
            [Bind(Prefix = "personEmail")] PersonEmailEntity personEmail,
            [Bind(Prefix = "phone")] PhoneEntity phone,
            [Bind(Prefix = "personPhone")] PersonPhoneEntity personPhone)
        {
            personAddress.Address = address;
            agent.PersonAddress[0] = personAddress;
            personEmail.Email = email;
            agent.PersonEmail[0].EmailTypeId = personEmail.EmailTypeId;
            personPhone.Phone = phone;
            agent.PersonPhone[0] = personPhone;

            if (ModelState.IsValid)
            {
                agent.Save(true);

                return RedirectToAction("List");
            }

            ViewData["AddressTypes"] = SelectListFactory.CreateSelectList(
                QueryService.FindAddressTypes(), personAddress.AddressTypeId, Resources.DropDownGeneric);
            ViewData["EmailTypes"] = SelectListFactory.CreateSelectList(
                QueryService.FindEmailTypes(), personEmail.EmailTypeId, Resources.DropDownGeneric);
            ViewData["PhoneTypes"] = SelectListFactory.CreateSelectList(
                QueryService.FindPhoneTypes(), personPhone.PhoneTypeId, Resources.DropDownGeneric);
            ViewData["States"] = SelectListFactory.CreateSelectList(QueryService.FindStates(), address.StateId, Resources.DropDownGeneric);

            return View(agent);
        }

What you don't see is when the agent object is created through the default binder, it is assigned the primary key representing the existing parent record and the IsNew field is set to false. All other objects are assigned values from the ASP.NET form.

Agent is a subtype of Person and Person has a many to many relationship with Address, Email and Phone.

I'm able to update fields on agent that result in updates. But the code above inserts new child records rather than update them...

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 15-Jul-2009 10:26:24   

What you don't see is when the agent object is created through the default binder, it is assigned the primary key representing the existing parent record and the IsNew field is set to false.

Similarly the child entities should have their PK set and IsNew should be set to false.

oq
User
Posts: 6
Joined: 17-Jun-2009
# Posted on: 15-Jul-2009 16:28:02   

I've now set IsNew to false and I've set the primary keys on all child entities. However, I have to set the primary keys outside the default binder, otherwise I receive a field is read-only error:


            address.Fields["Id"].ForcedCurrentValueWrite(Convert.ToInt32(Request.Form["addressId"]));
            personAddress.Fields["Id"].ForcedCurrentValueWrite(Convert.ToInt32(Request.Form["personAddressId"]));
            email.Fields["Id"].ForcedCurrentValueWrite(Convert.ToInt32(Request.Form["emailId"]));
            personEmail.Fields["Id"].ForcedCurrentValueWrite(Convert.ToInt32(Request.Form["personEmailId"]));
            phone.Fields["Id"].ForcedCurrentValueWrite(Convert.ToInt32(Request.Form["phoneId"]));
            personPhone.Fields["Id"].ForcedCurrentValueWrite(Convert.ToInt32(Request.Form["personPhoneId"]));

Please let me know if this method and overall process is viable.

Thanks.

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 15-Jul-2009 16:35:24   

I'm not that familiar yet with the ASP.NET MVC, but you can't find pass that PK value to the entity CTor, then your code is the way to go.

I think this should work fine, please send us your feedback.