Это сводит меня с ума. Надеюсь, мой вопрос имеет смысл ...
Я использую MVC 2 и Entity Framework 1 и пытаюсь вставить новую запись с двумя навигационными свойствами.
У меня есть таблица SQL, Категории, в которой есть таблица поиска CategoryTypes и другой самозависимый поиск CategoryParent. EF создает два свойства nav для моей модели Category, одно с именем Parent, а другое с CategoryType, оба экземпляра соответствующих моделей.
С моей точки зрения, которая создает новую категорию, у меня есть два раскрывающихся списка: один для типа категории, а другой для ParentCategory. Когда я пытаюсь вставить новую категорию БЕЗ ParentCategory, которая допускает нулевые значения, все в порядке. Как только я добавляю ParentCategory, вставка завершается неудачно, и странно (или я так думаю) жалуется на CategoryType в форме этой ошибки:
0 связанных "CategoryTypes" были найдены. 1 «CategoryTypes» ожидается.
Когда я прохожу, я могу убедиться, что оба свойства ID, входящие в параметр метода действия, верны. Я также могу убедиться, что когда я иду в базу данных, чтобы получить CategoryType и ParentCategory с идентификаторами, записи обрабатываются нормально. Тем не менее он не работает в SaveChanges ().
Все, что я вижу, это то, что мой раскрывающийся список CategoryParent для, на мой взгляд, каким-то образом вызывает вставку бомбы.
Пожалуйста, смотрите мои комментарии в моем методе действия httpPost Create.
Модель моего вида выглядит так:
public class EditModel
{
public Category MainCategory { get; set; }
public IEnumerable<CategoryType> CategoryTypesList { get; set; }
public IEnumerable<Category> ParentCategoriesList { get; set; }
}
Мои методы действий Create выглядят так:
// 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");
}
Я также закомментировал два моих выпадающих списка, чтобы эти свойства в "mainCategory" не создавались.
Итак, теперь, когда свойства nav равны нулю, я использую два литерала для идентификатора, и он работает отлично. В конечном счете, я хочу использовать идентификаторы Parent и CategoryType из mainCategory, но это, похоже, не работает. Вероятно, веская причина, о которой я не знаю?