0

Я искал по всему месту, нашел много вопросов, но ни один из них не ответил на мой вопрос.EF Вставьте ребенка в определенный родитель

Вещь я пытаюсь сделать, это просто, скажем, у нас есть что-то вроде этого:

public class Parent 
{ 
    public int ID { get; set; } 

    public List<Child> Children { get; set; } 
} 

public class Child 
{ 
    public int ID { get; set; } 

    public int ParentID { get; set; } 
    public Parent Parent { get; set; } 
} 

EF заботится о создании БД и через строительные леса я получаю контроллеры и представления. Все работает нормально, я могу создать родителя. Я также могу создать Child с ParentID, выбранным из раскрывающегося списка.

То, что я действительно хочу сделать, это удалить выпадающий и передать ParentID в качестве параметра, как, что:

public IActionResult Create(int id) 
    { 
     if (id == 0) 
     { 
      return NotFound(); 
     } 

     ViewData["ID"] = id; //that a ParentID 
     return View(); 
    } 

И в виду мы получили это:

<form asp-action="Create"> 
    <div class="form-horizontal"> 
     <h4>Child</h4> 
     <hr /> 
     <div asp-validation-summary="ModelOnly" class="text-danger"></div> 
     <input type="hidden" asp-for="ParentID" [email protected]["ID"] /> 
     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Create" class="btn btn-default" /> 
      </div> 
     </div> 
    </div> 
</form> 

При подаче этого я получил «Не могу вставьте явное значение для столбца идентификации в таблицу «Дети», если для параметра IDENTITY_INSERT установлено значение «ВЫКЛ». » Теперь я посмотрел повсюду и попробовал различные атрибуты, но все же я не могу заставить это работать.

Буду признателен за любую помощь.


Update

Создать метод из контроллера:

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public async Task<IActionResult> Create([Bind("ID,ParentID")] Child child) 
    { 
     if (ModelState.IsValid) 
     { 
      _context.Add(child); 
      await _context.SaveChangesAsync(); 
      return RedirectToAction("Index"); 
     } 
     return View(book); 
    } 

Просто, чтобы показать больше о проблеме. Здесь я использую версию по умолчанию для подмостей с выбранным элементом управления.

public IActionResult Create(int id) 
    { 
     if (id == 0) 
     { 
      return NotFound(); 
     } 

     ViewData["ParentID"] = new SelectList(_context.Parents.Where(x => x.ID == 1), "ID", "ID"); //Works 
     ViewData["ParentID"] = new SelectList(_context.Parents.Where(x => x.ID == id), "ID", "ID"); // Doesn't work 
     return View(); 
    } 
+0

Можете ли вы разместить код, который составляет фактический объект 'Child'? Ошибка, похоже, указывает на то, что вы пытаетесь явно установить значение для поля, которое EF помечено как столбцы идентификации. Если он не будет неправильно установлен, «ParentID» не должен быть столбцом «Identity» в «Child» –

+0

@ stephen.vakil Спасибо за ваш ответ, завтра я буду на работе, и я смогу опубликовать его, но я не сделал этого, ничего не меняйте, кроме того, что я показал. Он выдает исключение в этой строке «Ожидание _context.SaveChangesAsync();». – Bielik

+0

сохраните parentID как скрытый на вид внутри формы и этим он вернется с сообщением – Monah

ответ

0

После разговора с людьми в комментариях, я начинаю думать, что проблема вызвана ошибкой в ​​EF Ядра, но я думаю, что я нашел «грязную» работу вокруг.

Вот Ребенок модель:

public class Child 
{ 
    [DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public int ID { get; set; } 

    [DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public int ParentID { get; set; } 
    [ForeignKey("ParentID")] 
    public Parent Parent { get; set; } 
} 

В настоящее время (по некоторым причинам) это решает «Не удается вставить явное значение для столбца идентификаторов в таблице„Дети“, когда IDENTITY_INSERT установлен в положение OFF.» но создает новые, мы не получаем уникальный идентификатор. Я установил, что, делая это сам, здесь создать метод:

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public async Task<IActionResult> Create([Bind("ID,ParentID")] Child child) 
    { 
     if (ModelState.IsValid) 
     { 
      int _id; 
      do 
      { 
       _id = new Random().Next(); 
      } while (await _context.Children.Where(b => b.ID == _id).AnyAsync()); 

      child.ID = _id; 
      _context.Add(child); 
      await _context.SaveChangesAsync(); 
      return RedirectToAction("Index"); 
     } 
     ViewData["ID"] = id; 
     return View(child); 
    } 

Теперь doWhile убеждается, что мы не назначайте один и тот же идентификатор для двух различных объектов. Альтернативы произвольной опции - использовать Guid (когда id - строка) или GetHashCode (и приращение при столкновении возможно).

Смежные вопросы