Finalmente he conseguido que esto funcione después de días de lucha.Very-Typed ASP.NET MVC con ADO.NET Entity Framework
Tengo una base de datos simple de las personas y departamentos:
puedo usar vistas inflexible de ASP.NET MVC para las propiedades de referencia/de navegación! Ver la lista de departamentos ...
ASP.NET MVC with DropDownList http://img11.imageshack.us/img11/7619/dropdownlistdepartment.gif
Parte de mi opinión de la persona/Editar:
<% 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>
<% } %>
Parte de mi controlador de Persona:
//
// 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");
}
Para conseguir este trabajo, Extendí Person EntityObject con una nueva propiedad DepartmentId.
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);
}
}
}
}
Y extendió el Entity Framework ObjectContext con nuevos métodos y AttachUpdated ApplyReferencePropertyChanges:
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); //extension
}
else
{
throw new ObjectNotFoundException();
}
}
}
public static void ApplyReferencePropertyChanges(this ObjectContext ctx, IEntityWithRelationships newEntity, IEntityWithRelationships oldEntity)
{
foreach (var relatedEnd in oldEntity.RelationshipManager.GetAllRelatedEnds())
{
var oldRef = relatedEnd as EntityReference;
if (oldRef != null)
{
var newRef = newEntity.RelationshipManager.GetRelatedEnd(oldRef.RelationshipName, oldRef.TargetRoleName) as EntityReference;
oldRef.EntityKey = newRef.EntityKey;
}
}
}
}
sólo quería documentar mi progreso aquí. Por favor sugiere mejoras
Gracias:
- Alex James
- Cesar de la Torre
- Griff Townsend
- Steve Willcock
- jrista
- Tomas Lycken
- Thomas Levesque
- Danny Simmons
- Stefan Cruysberghs
Buen trabajo, pero desafortunadamente stackoverflow.com no es el lugar para documentar su progreso. He votado para cerrar: "no es una pregunta real". –
¿No necesita excluir la propiedad de ID cuando vincula el objeto persona aquí: public ActionResult Edit (ID de guía, modelo de persona)? –
Ah, me perdí la parte de "sugerir mejoras". Déjalo vivir, digo. –