提交包含部分数据的表单以更新行

时间:2017-11-25 18:48:04

标签: c# asp.net entity-framework

我正在使用ASP.NET Core和Entity Framework Core。 这是我的表的定义:

public class Order
{
    public int Id { get; set; }
    public int Year { get; set; }
    public int Number { get; set; }
    public int CustomerId { get; set; }
    public double Quantity { get; set; }
}

在页面I中只显示了一些字段,即:

<form method="post">
    <div style="overflow: auto; max-height: 400px;">
        <table class="table table-responsive table-hover">
            <thead class="thead-light">
                <tr>
                    <th scope="col">
                        @Html.DisplayNameFor(model => model.Orders[0].Number)
                    </th>
                    <th scope="col">
                        @Html.DisplayNameFor(model => model.Orders[0].Quantity)
                    </th>
                </tr>
            </thead>
            <tbody>
                @foreach (var item in Model.Orders)
                {
                    <tr>
                        <th scope="row">
                            @Html.DisplayFor(modelItem => item.Number)
                        </th>
                        <td scope="row">
                            <input type="number" value="@Html.DisplayFor(modelItem => item.Quantity)" asp-for="Order.Quantity"/>
                        </td>
                    </tr>
                }
            </tbody>
        </table>
    </div>

    <input type="submit" value="@Resources.Save" class="btn btn-success" />
</form>

这里是cs代码:

[BindProperty]
public Order Order { get; set; }

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Orders.Attach(Order).State = EntityState.Modified;

    try
    {
        await _context.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        throw new System.Exception($"Order {Order.Id} not found!");
    }
    return RedirectToPage();
}

但是我收到以下错误:

  

InvalidOperationException:属性&#39; Id&#39;在实体类型&#39;订单&#39;在尝试将实体的状态更改为“已修改”时具有临时值。可以显式设置永久值,也可以确保将数据库配置为为此属性生成值。

经过一些研究,这似乎意味着EF正在等待显式设置的Id字段,因为生成的临时密钥无法存储到数据库中。

可是:

  1. 我的主键(Id)是int,因此它应该自动生成
  2. 最重要的是,我正在更新现有的记录,ID已存在于数据库中。
  3. 这是由于我提交的部分数据吗?我不想向用户显示所有字段,将数据放入隐藏字段似乎也不是一个好主意。

1 个答案:

答案 0 :(得分:0)

您想要检索记录列表,因此您必须根据以下内容进行绑定:

[BindProperty]
public List<Order> ListOrders { get; set; }

然后在View中,使用for循环而不是foreach,所以你有一个索引:

@for (int i = 0; i < Model.Orders.Count; i++)
{
    ...
    <tr>
        <td scope="row">
            <input asp-for="ListOrders[i].Quantity" value="@Model.Orders[i].Quantity" readonly />
        </td>
    </tr>
    ...
}

不幸的是,您必须将所有字段(即使隐藏)放入表单中。