简体   繁体   English

EF将孩子插入特定的父母

[英]EF Insert Child to specific Parent

I have been searching all over the place, found many questions but neither of them answer my. 我到处搜寻,发现许多问题,但没有一个回答我。

Thing I am trying to do is simple, let's say we have something like that: 我想做的事情很简单,假设我们有这样的事情:

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 takes care of creating db and via scaffolding I get controllers and views. EF负责创建数据库,并通过脚手架获得控制器和视图。 Everything works fine, I can create Parent. 一切正常,我可以创建Parent。 I can also create Child with ParentID chosen from drop down. 我也可以使用从下拉列表中选择的ParentID创建Child。

What I really want to do is remove drop down and pass ParentID as parameter like that: 我真正想做的是删除下拉列表,然后将ParentID作为参数传递:

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

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

And in view we got this: 鉴于我们得到了这个:

<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" value=@ViewData["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>

When submitting this I got "Cannot insert explicit value for identity column in table 'Children' when IDENTITY_INSERT is set to OFF." 提交此消息时,出现“当IDENTITY_INSERT设置为OFF时,无法为表'Children'中的Identity列插入显式值”。 Now I looked all over the place and tried various attributes yet still I can't get this to work. 现在我环顾四周,尝试了各种属性,但仍然无法正常工作。

I will be grateful for any sort of help. 我将不胜感激。


Update 更新资料

Create method from controller: 从控制器创建方法:

    [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);
    }

Just to show more about problem. 只是为了显示更多有关问题的信息。 Here I am using default scaffolded version with select control in view. 在这里,我使用默认的脚手架版本,并带有选择控件。

    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();
    }

After talking with people in comments I start to think that problem is caused by a bug in EF Core but I think I have found 'dirty' work around. 在评论中与人交谈之后,我开始认为问题是由EF Core中的错误引起的,但我认为我发现“脏”的解决方法。

Here is Child model: 这是子模型:

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; }
}

Now (for some reason) this solves "Cannot insert explicit value for identity column in table 'Children' when IDENTITY_INSERT is set to OFF." 现在(由于某种原因)解决了“当IDENTITY_INSERT设置为OFF时,无法在表'Children'中为Identity列插入显式值”。 issue but creates new, we don't get unique id. 问题,但创建了新的,我们没有唯一的ID。 I fixed that by making it myself, here is create method: 我通过自己修复此问题,这是create方法:

    [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);
    }

Now doWhile makes sure that we don't assign the same id to two different objects. 现在,doWhile确保我们不会将相同的ID分配给两个不同的对象。 Alternatives to Random option are to use Guid (when id is string) or GetHashCode (and increment in case of collision perhaps). 随机选项的替代方法是使用Guid(当id为字符串时)或GetHashCode(并在发生冲突的情况下递增)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM