Entity framework MVC 2实体框架视图模型插入
这让我快发疯了。希望我的问题有意义 我正在使用MVC2和EntityFramework1,并试图插入一个带有两个导航属性的新记录 我有一个SQL表Categories,它有一个查找表categoritypes和另一个自引用查找categorityparent。EF在我的类别模型上创建了两个nav属性,一个称为Parent,另一个称为CategoryType,这两个属性都是各自模型的实例 在创建新类别的视图中,我有两个下拉列表,一个用于CategoryType,另一个用于ParentCategory。当我尝试在没有ParentCategory的情况下插入新类别时(ParentCategory允许空值),一切都很好。我一添加ParentCategory,插入就失败了,奇怪的是(或者我认为是这样)以错误的形式抱怨CategoryType: 找到0个相关的“CategoryTypes”。应为1个“类别类型” 当我逐步完成时,我可以验证action方法参数中的两个ID属性是否正确。我还可以验证,当我去db获取带有ID的CategoryType和ParentCategory时,记录被很好地提取出来。但它在SaveChanges()上失败 我所能看到的是,在我看来,我的CategoryParent dropdownlistfor某种程度上导致了插件爆炸 请在我的httpPost创建操作方法中查看我的评论 我的视图模型如下所示:Entity framework MVC 2实体框架视图模型插入,entity-framework,asp.net-mvc-2,Entity Framework,Asp.net Mvc 2,这让我快发疯了。希望我的问题有意义 我正在使用MVC2和EntityFramework1,并试图插入一个带有两个导航属性的新记录 我有一个SQL表Categories,它有一个查找表categoritypes和另一个自引用查找categorityparent。EF在我的类别模型上创建了两个nav属性,一个称为Parent,另一个称为CategoryType,这两个属性都是各自模型的实例 在创建新类别的视图中,我有两个下拉列表,一个用于CategoryType,另一个用于ParentCategor
public class EditModel
{
public Category MainCategory { get; set; }
public IEnumerable<CategoryType> CategoryTypesList { get; set; }
public IEnumerable<Category> ParentCategoriesList { get; set; }
}
// GET: /Categories/Create
public ActionResult Create()
{
return View(new EditModel()
{
CategoryTypesList = _db.CategoryTypeSet.ToList(),
ParentCategoriesList = _db.CategorySet.ToList()
});
}
// POST: /Categories/Create
[HttpPost]
public ActionResult Create(Category mainCategory)
{
if (!ModelState.IsValid)
return View(new EditModel()
{
MainCategory = mainCategory,
CategoryTypesList = _db.CategoryTypeSet.ToList(),
ParentCategoriesList = _db.CategorySet.ToList()
});
mainCategory.CategoryType = _db.CategoryTypeSet.First(ct => ct.Id == mainCategory.CategoryType.Id);
// This db call DOES get the correct Category, but fails on _db.SaveChanges().
// Oddly the error is related to CategoryTypes and not Category.
// Entities in 'DbEntities.CategorySet' participate in the 'FK_Categories_CategoryTypes' relationship.
// 0 related 'CategoryTypes' were found. 1 'CategoryTypes' is expected.
//mainCategory.Parent = _db.CategorySet.First(c => c.Id == mainCategory.Parent.Id);
// If I just use the literal ID of the same Category,
// AND comment out the CategoryParent dropdownlistfor in the view, all is fine.
mainCategory.Parent = _db.CategorySet.First(c => c.Id == 2);
_db.AddToCategorySet(mainCategory);
_db.SaveChanges();
return RedirectToAction("Index");
}
以下是我在视图上创建的表单:
<% using (Html.BeginForm()) {%>
<%= Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<div>
<%= Html.LabelFor(model => model.MainCategory.Parent.Id) %>
<%= Html.DropDownListFor(model => model.MainCategory.Parent.Id, new SelectList(Model.ParentCategoriesList, "Id", "Name")) %>
<%= Html.ValidationMessageFor(model => model.MainCategory.Parent.Id) %>
</div>
<div>
<%= Html.LabelFor(model => model.MainCategory.CategoryType.Id) %>
<%= Html.DropDownListFor(model => model.MainCategory.CategoryType.Id, new SelectList(Model.CategoryTypesList, "Id", "Name"))%>
<%= Html.ValidationMessageFor(model => model.MainCategory.CategoryType.Id)%>
</div>
<div>
<%= Html.LabelFor(model => model.MainCategory.Name) %>
<%= Html.TextBoxFor(model => model.MainCategory.Name)%>
<%= Html.ValidationMessageFor(model => model.MainCategory.Name)%>
</div>
<div>
<%= Html.LabelFor(model => model.MainCategory.Description)%>
<%= Html.TextAreaFor(model => model.MainCategory.Description)%>
<%= Html.ValidationMessageFor(model => model.MainCategory.Description)%>
</div>
<div>
<%= Html.LabelFor(model => model.MainCategory.SeoName)%>
<%= Html.TextBoxFor(model => model.MainCategory.SeoName, new { @class = "large" })%>
<%= Html.ValidationMessageFor(model => model.MainCategory.SeoName)%>
</div>
<div>
<%= Html.LabelFor(model => model.MainCategory.HasHomepage)%>
<%= Html.CheckBoxFor(model => model.MainCategory.HasHomepage)%>
<%= Html.ValidationMessageFor(model => model.MainCategory.HasHomepage)%>
</div>
<p><input type="submit" value="Create" /></p>
</fieldset>
<% } %>
我还注释掉了我的两个DropDownList,这样“mainCategory”上的属性就不会被实例化
因此,现在2个nav属性为空,我使用两个文本作为Id,它可以完美地工作。最后,我想使用mainCategory中父级和CategoryType的Id,但这似乎不起作用。可能是我不知道的一个很好的原因?您是否尝试将EntityReference设置为
mainCategory.CategoryTypeReference.EntityKey = new EnityKey("YourEntities", "Id", mainCategory.CategoryType.Id);
这样,您就不必加载CategoryType,它可能会解决您的问题
编辑:我发布的示例不完整,抱歉,以下是您应该做的
int parentId = mainCategory.Parent.Id;
short typeId = mainCategory.CategoryType.Id;
mainCategory.Parent = null;
mainCategory.CategoryType = null;
mainCategory.ParentReference.EntityKey = new EntityKey("DbEntities.CategorySet", "Id", parentId);
mainCategory.CategoryTypeReference.EntityKey = new EntityKey("DbEntities.CategoryTypeSet", "Id", typeId);
在设置CategoryType并毫无疑问地确认属性已填充之后,是否设置了断点?嗨,Dave。是的,我可以通过断点确认mainCategory.CategoryType仅使用表单提交中的Id填充,然后使用_db.CategoryTypeSet调用中的父类别填充。在设置
CategoryType之前,请尝试调用AddToCategorySet
;那有用吗?嘿,克雷格。我的类别上的CategoryType不可为null,因此这会导致无法插入null值错误。我觉得我必须告诉你,你在这里的其他帖子已经帮助了我很多次,所以谢谢!当我的操作方法参数maincography.Parent从我的表单帖子或在我的控制器中实例化时,不知何故会导致此错误。我开始认为它与强类型html帮助程序有某种联系,就像我以前在MVC1中所做的那样,没有任何问题。否则我就忽略了一些非常愚蠢的事情。你仍然需要设置CategoryType
。只需先调用AddToCategorySet
。只要在调用SaveChanges
之前设置CategoryType
,就不会出现空错误。我确实喜欢这种为EF 1.0版添加外键的方式,但不幸的是,它在插入时的行为与此相同,但只有在我添加CategoryType和父类别时才会出现。如果省略父类别,两种方法都可以。你的方式肯定是最有效的。请看我的编辑,忘记告诉我你必须将父级和CategoryType设置为null,这样就不会有引用问题,他们可能会有Welp,这就成功了!!!我基本上就是按照你说的做的,认为我必须把那些导航属性设置为null有点奇怪。但它是有效的!在我的编辑方法中,我不必为这些属性设置空值,所以我想这只适用于插入。无论如何,谢谢你,妈妈。。。还有所有尝试过的人!
int parentId = mainCategory.Parent.Id;
short typeId = mainCategory.CategoryType.Id;
mainCategory.Parent = null;
mainCategory.CategoryType = null;
mainCategory.ParentReference.EntityKey = new EntityKey("DbEntities.CategorySet", "Id", parentId);
mainCategory.CategoryTypeReference.EntityKey = new EntityKey("DbEntities.CategoryTypeSet", "Id", typeId);