2010-03-31 27 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