这让我疯狂。希望我的问题是有道理的...MVC 2实体框架查看模型插入
我正在使用MVC 2和实体框架1,并试图插入一个新的记录与两个导航属性。
我有一个SQL表,类别,它有一个查找表CategoryTypes和另一个自我引用查找CategoryParent。 EF在我的类别模型上创建了两个导航属性,一个名为Parent,另一个名为CategoryType,两个模型都是实例。
在我的观点,创建新的类别,我有两个下拉菜单,一个为CategoryType和另一个为ParentCategory。当我尝试插入新的类别而没有允许空值的ParentCategory时,一切都很好。只要我添加ParentCategory,插入失败,奇怪(或者我认为)以此错误的形式抱怨CategoryType:
0找到相关'CategoryTypes'。预计会有''CategoryTypes''。
当我通过时,我可以验证action方法参数上的两个ID属性是否正确。我也可以验证,当我去db获取带有ID的CategoryType和ParentCategory时,记录被拉好。然而,它在SaveChanges()上失败。
所有我能看到的是,我的CategoryParent dropdownlist在我看来,是以某种方式导致插入炸弹。
请在我的httpPost创建操作方法中看到我的意见。
我的视图模型是这样的:
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>
<% } %>
也许我一直熬夜玩MVC 2? :)请让我知道,如果我不够清楚。
自从问这个问题后我改变了一些东西。我觉得我很近?
我的新创建的操作方法:
private DbEntities _db = new DbEntities();
// 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()
});
int parentId = 2; // Accessories in db.
short typeId = 1; // Product type in db.
mainCategory.ParentReference.EntityKey = new EntityKey("DbEntities.CategorySet", "Id", parentId);
mainCategory.CategoryTypeReference.EntityKey = new EntityKey("DbEntities.CategoryTypeSet", "Id", typeId);
_db.AddToCategorySet(mainCategory);
_db.SaveChanges();
return RedirectToAction("Index");
}
我也注释掉我的两个dropdownlists等“mainCategory”的属性不被实例化。
因此,现在使用2个导航属性为null,我使用了两个文字作为Id,它完美地工作。最终,我想使用mainCategory的Parent和CategoryType的Id,但这似乎不起作用。可能是我不知道的一个很好的理由?
你设置一个断点右侧设置了CategoryType并确认毫无疑问,该酒店后被填充? – 2010-03-31 03:19:30
嗨戴夫。是的,我可以通过断点来确认mainCategory.CategoryType是通过表单提交填充了Id,然后用_db.CategoryTypeSet调用的父类别填充。 – JasperLamarCrabb 2010-03-31 03:47:34
在*设置CategoryType之前尝试调用'AddToCategorySet' *;这有帮助吗? – 2010-03-31 12:45:37