2010-03-31 23 views
0

这让我疯狂。希望我的问题是有道理的...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,但这似乎不起作用。可能是我不知道的一个很好的理由?

+0

你设置一个断点右侧设置了CategoryType并确认毫无疑问,该酒店后被填充? – 2010-03-31 03:19:30

+0

嗨戴夫。是的,我可以通过断点来确认mainCategory.CategoryType是通过表单提交填充了Id,然后用_db.CategoryTypeSet调用的父类别填充。 – JasperLamarCrabb 2010-03-31 03:47:34

+0

在*设置CategoryType之前尝试调用'AddToCategorySet' *;这有帮助吗? – 2010-03-31 12:45:37

回答

1

你有没有尝试设置的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); 
+0

我不喜欢加入对EF 1.0版本外键的这种方式,但不幸的是,它的行为上插入相同的方式,但只有当我有一个父类旁边加上CategoryType。如果我省略父类别,两种方式都可以正常工作。你的方式当然是最有效的。 – JasperLamarCrabb 2010-03-31 03:53:02

+0

见我的编辑,忘了告诉你必须设置父和CategoryType为空,这样不会有参照的问题,他们可能有 – 2010-04-01 01:00:42

+0

韦尔普,该诀窍!我基本上只是做了你在这里所说的,认为我有必要将这些导航属性设置为空有点奇怪。但它的作品!在我的编辑方法中,我不需要清空这些属性,所以我想这只适用于插入。无论如何,谢谢你moi_meme !!!!!!!!! ......而每个人都刺伤了这个! – JasperLamarCrabb 2010-04-01 02:37:12