MVC 2实体框架查看模型插入
这让我疯狂。希望我的问题是有道理的...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,但这似乎不起作用。可能是我不知道的一个很好的理由?
你有没有尝试设置的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);
我不喜欢加入对EF 1.0版本外键的这种方式,但不幸的是,它的行为上插入相同的方式,但只有当我有一个父类旁边加上CategoryType。如果我省略父类别,两种方式都可以正常工作。你的方式当然是最有效的。 – JasperLamarCrabb 2010-03-31 03:53:02
见我的编辑,忘了告诉你必须设置父和CategoryType为空,这样不会有参照的问题,他们可能有 – 2010-04-01 01:00:42
韦尔普,该诀窍!我基本上只是做了你在这里所说的,认为我有必要将这些导航属性设置为空有点奇怪。但它的作品!在我的编辑方法中,我不需要清空这些属性,所以我想这只适用于插入。无论如何,谢谢你moi_meme !!!!!!!!! ......而每个人都刺伤了这个! – JasperLamarCrabb 2010-04-01 02:37:12
你设置一个断点右侧设置了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