I finally got this job after several days of struggle.
I have a simple database of people and departments:
Entity Framework Entity Data Model Diagram with Department and Person objects http://img39.imageshack.us/img39/1368/edmxdepartmentperson.gif
I can use strongly typed ASP.NET MVC views for link / navigation properties! See the list of departments ...
ASP.NET MVC with DropDownList http://img11.imageshack.us/img11/7619/dropdownlistdepartment.gif
Part of my face / Edit view:
<% using (Html.BeginForm()) {%> <%= Html.Hidden("Id", Model.Id) %> <fieldset> <legend>Fields</legend> <p> <label for="Name">Name:</label> <%= Html.TextBox("Name", Model.Name) %> </p> <p> <label for="DepartmentId">Department:</label> <%= Html.DropDownList("DepartmentId", new SelectList((IEnumerable)ViewData["Departments"], "Id", "Name"))%> </p> <p> <input type="submit" value="Save" /> </p> </fieldset> <% } %>
Part of my Person controller:
// // GET: /Person/Edit/5 public ActionResult Edit(Guid id) { ViewData["Departments"] = ctx.Department; Person model = (from Person p in ctx.Person where p.Id == id select p).FirstOrDefault(); return View(model); } // // POST: /Person/Edit [AcceptVerbs(HttpVerbs.Post)] public ActionResult Edit(Person model) { ctx.AttachUpdated(model); //extension ctx.SaveChanges(); return RedirectToAction("Index"); }
To get this working, I extended the Person EntityObject with the new DepartmentId property.
using System; using System.Data; using System.Data.Objects.DataClasses; namespace ProjectName.Models { public partial class Person : EntityObject { public Guid DepartmentId { get { try { return (Guid)this.DepartmentReference.EntityKey.EntityKeyValues[0].Value; } catch { return Guid.Empty; } } set { this.DepartmentReference.EntityKey = new EntityKey("JunkEntities.Department", "Id", value); } } } }
And I expanded the ObjectContext of the Entity Framework object with the new AttachUpdated and ApplyReferencePropertyChanges methods:
using System; using System.Data; using System.Data.Objects; using System.Data.Objects.DataClasses; public static class EntityFrameworkExtensionMethods { public static void AttachUpdated(this ObjectContext ctx, EntityObject objectDetached) { if (objectDetached.EntityKey == null) { String entitySetName = ctx.DefaultContainerName + "." + objectDetached.GetType().Name; Guid objectId = (Guid)objectDetached.GetType().GetProperty("Id").GetValue(objectDetached, null); objectDetached.EntityKey = new System.Data.EntityKey(entitySetName, "Id", objectId); } if (objectDetached.EntityState == EntityState.Detached) { object currentEntityInDb = null; if (ctx.TryGetObjectByKey(objectDetached.EntityKey, out currentEntityInDb)) { ctx.ApplyPropertyChanges(objectDetached.EntityKey.EntitySetName, objectDetached); ctx.ApplyReferencePropertyChanges((IEntityWithRelationships)objectDetached, (IEntityWithRelationships)currentEntityInDb);
I just wanted to document my progress here. Please suggest improvements.
Thank: