【发布时间】:2013-08-06 18:41:49
【问题描述】:
经过几天的努力,我终于完成了这项工作。
我有一个简单的人员和部门数据库:
我可以将强类型的 ASP.NET MVC 视图用于引用/导航属性!查看部门列表...
ASP.NET MVC with DropDownList http://img11.imageshack.us/img11/7619/dropdownlistdepartment.gif
我的个人/编辑视图的一部分:
<% 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>
<% } %>
我的 Person 控制器的一部分:
//
// 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");
}
为了让它工作,我用一个新的 DepartmentId 属性扩展了 Person EntityObject。
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);
}
}
}
}
我使用新的 AttachUpdated 和 ApplyReferencePropertyChanges 方法扩展了实体框架 ObjectContext:
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;
}
}
}
}
我只是想在这里记录我的进步。请提出改进建议。
谢谢:
【问题讨论】:
-
干得好,但不幸的是 stackoverflow.com 不是您记录进度的地方。我投票结束:“不是一个真正的问题”。
-
这里绑定person对象时不需要排除id属性吗:public ActionResult Edit(Guid id, Person Model)?
-
啊,我错过了关于“建议改进”的部分。我说,让它活下去吧。
-
如果我在这里输入一个伪造的 ID 怎么办:public ActionResult Edit(Guid id)?您不会检查是否存在具有该 ID 的人,如果不存在则不会向用户显示错误。
-
就像说我很高兴这被留下来“活着”,并且 stackoverflow 应该可以灵活地让人们记录这样的东西。有几个原因。 1)。它在搜索中排名很高,让其他开发人员从中学习。即社区利益。 2)像这样的支持材料可以用于其他问题的答案。
标签: asp.net-mvc entity-framework ado.net