2017-01-06 15 views
0

У меня возникла проблема с созданием объекта. У моей сущности «иерархические» отношения «один ко многим». Раздел может принадлежать другому подразделению. Вот моя сущность:MVC4, EF: Создать новый объект с «иерархическим» отношением «один ко многим»

//Properties 
    [Key] 
    [Column(Order = 0)] 
    public int DivisionId { get; set; } 

    [Required] 
    [MaxLength(30)] 
    [Column("DivisionName", Order = 2)] 
    public string Name { get; set; } 

    //Navigation properties 
    public virtual Division ParentDivision { get; set; } 

Вот мой метод, чтобы создать новое подразделение:

public ActionResult Create() 
    { 
     ViewBag.ParentDivision = new SelectList(db.Divisions, "DivisionId", "Name"); 
     return View(); 
    } 


    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Create(Division division) 
    {    
     if (ModelState.IsValid) 
     { 
      db.Divisions.Add(division); 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 

     ViewBag.ParentDivision = new SelectList(db.Divisions, "DivisionId", "Name", division.ParentDivision.DivisionId); 
     return View(division); 
    } 

В этом случае, когда я пытаюсь создать подразделение, которое принадлежит другой отдел, я получаю "В экземпляре объекта не задана ссылка на объект." ошибка.

Я также попытался изменить ViewBag так:

ViewBag.ParentDivision = new SelectList(db.Divisions, "ParentDivision.DivisionId", "Name", division.ParentDivision.DivisionId); 

Здесь создается объект, но без родительского деления ...

Я действительно путают ... Если у кого-то есть идея ... Спасибо заранее.

+0

Вы действительно имеете в виду «круговой»? то есть подразделение A владеет B, которому принадлежит A? Или вы имеете в виду «иерархический»? А владеет B, C, D; C владеет E, F и т. Д., Но он никогда не возвращается к A? –

+0

@AdamBenson Да, извините, как вы говорите, это иерархический, а не круговой, спасибо – Pookye

ответ

0

Это не имеет никакого отношения к тому факту, что это отношение, связанное со ссылками. Если ParentDivision еще не установлен, оно будет равно null, а значение null не будет иметь свойства DivisionId, следовательно, ваше исключение.

Вам необходимо сделать нулевую проверку перед ссылкой на свойство. Возможно, самый простой способ в данном случае было бы с помощью трехкомпонентной:

division.ParentDivision != null ? division.ParentDivision.DivisionId : null 

Однако, вам не нужно, чтобы установить выбранное значение, в любом случае. Razer позаботится об этом автоматически. Вам также не нужно создавать фактический SelectList. Все Html.DropDownListFor потребностей - IEnumerable<SelectListItem>. Если вы его передадите, помощник позаботится о создании SelectList и установит соответствующее выбранное значение, если это применимо.

ViewBag.ParentDivision = db.Divisions.Select(m => new SelectListItem { Value = m.DivisionId, Text = m.Name }); 

Тогда:

@Html.DropDownListFor(m => m.ParentDivisionId, (IEnumerable<SelectListItem>)ViewBag.ParentDivision) 

Который поднимает другой вопрос. В настоящее время у вас нет свойства для привязки. Вы не можете использовать ParentDivision напрямую, потому что в списке выбора будет отображаться только идентификатор, а не полный экземпляр ParentDivision. Вам нужно имущество, чтобы связать отправленный идентификатор, что является хорошей практикой для включения в вашу организацию:

[ForeignKey("ParentDivision")] 
public int ParentDivisionId { get; set; } 
public virtual Division ParentDivision { get; set; } 
+0

Спасибо! Фактически я удалил всю свою сущность и переделал ее с учетом вашей последней точки. Я также добавил коллекцию детей, и когда я обновил базу данных, я увидел разницу в генерируемой таблице. – Pookye