How to fake Foreign Key Collections Properties in Entity Framework and ASP.NET MVC
Asked Answered
C

1

3

In Alex James' blog post How to fake Foreign Key Properties in .NET 3.5 SP1, he explains how to add a Foreign Key property to an Entity Object.

I've used that to get a reference/navigation property working with a DropDownList in a strongly-typed ASP.NET MVC application as explained here:

Strongly-Typed ASP.NET MVC with ADO.NET Entity Framework

I need to also handle collections. I can use Tyler Garlick's CheckBoxList rather than the built-in DropDownList.

ASP.NET MVC With CheckBoxList http://img241.imageshack.us/img241/5197/checkboxlistpeople.gif

But how do I extend the ObjectContext and my EntityObjects to handle one-to-many type relationships?

Do I extend my Department EntityObject class to include a PersonIds property of type Generic List of Guid? How do I handle the set accessor?

Countryman answered 28/5, 2009 at 21:53 Comment(0)
C
1

I'm assuming you can get the selected Person Id's into the Action method, and all the People already exist in the database... because this form is simply creating relationships to People and updating the department itself, not creating new staff.

In that case you want to do something like this (psuedo-code):

// get the department from the form using the model binder
Department updated = ... ;

// get the ids of the selected people from the form too.
var currentlySelectedStaffIds = ...;

// get the original department from the database 
// including the originally related staff
Department original = ctx.Departments.Include("Staff")
                      .First(dep => dep.Id = updated.Id);

// get the ids of all the originally related staff
var originalStaffIds = original.Staff.Select(s => s.Id).ToArray();

// get the People to be removed from the department
var removedStaff = (from staff in original.Staff
                   where !currentlySelectedStaffIds.Contains(staff.Id)
                   select staff).ToArray();

// get People added to the department (but attached to the context)
var addedStaff = currentlySelectedStaffIds.Except(originalStaffIds)
                 .Select(id => new Person {Id = id}).ToArray();

// Remove the original staff no longer selected.
foreach(var removed in removedStaff)
{
    original.Staff.Remove(removed);
}

// Attach the 'added' staff and build a new relationship for each one
foreach(var added in addedStaff){
   //Put the staff added to the department in the context
   ctx.AttachTo("People", added); 
   // build a new relationship
   original.Staff.Add(added); 
}

// Apply the changes from updated to the original entity
ctx.ApplyPropertyChanges("Departments", updated);
ctx.SaveChanges();

This is essentially what you need to do..

Hope this helps

Alex

Cannibal answered 29/5, 2009 at 1:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.