0

我有一个项目,我使用 EntityFramework Code First 来管理数据库。我为此使用的模型如下:

[Table("Data")]
public class Data
{
    [Key, Column("Id")]
    public int Id { get; set; }

    [Column("Code")]
    public string Code { get; set; }

    [Column("Name")]
    public string Name { get; set; }

    [Column("Description")]
    public string Description { get; set; }

    public virtual List<DataAttribute> Attributes { get; set; }
}

[Table("DataAttribute")]
public class DataAttribute
{
    [Key, Column("Id")]
    public int Id { get; set; }

    [Column("IdData"), ForeignKey("Data")]
    public int IdData { get; set; }

    [Column("Name")]
    public string Name { get; set; }

    [Column("Description")]
    public string Description { get; set; }

    public virtual Data Data { get; set; }
}

我遇到的问题是当我尝试编辑 Data 对象(及其相关的 DataAttribute 值)时。在提交包含 Data 元素和 DataAttribute 元素的表单时,我没有正确映射它。我举一个 .cshtml 文件的例子。

@model MVCTestApp.Models.Data
@{
    ViewBag.Title = "Edit";
}
@section Scripts {
    <script type="text/javascript">
        $(function () {
            $('#new-row').click(function () {
                $('table tbody').append(
                    '<tr>' +
                    '<td><input class="name" type="text" /></td>' +
                    '<td><input class="description" type="text" /></td>' +
                    '<td><a class="delete" href="#">Delete</a></td>' +
                    '</tr>'
                );
                $('.delete').click(function () {
                    $(this).parent().parent().remove();
                });
            });
        });
    </script>
}
@using (@Html.BeginForm("Edit", "Data", FormMethod.Post)) {
    @Html.HiddenFor(a => a.Id)
Name:
    <br />
    @Html.TextBoxFor(a => a.Name)
    <br />
Description:
    <br />
    @Html.TextBoxFor(a => a.Description)
    <br />
Code:
    <br />
    @Html.TextBoxFor(a => a.Code)
    <br />
    <table>
        <thead>
            <tr>
                <th>
                    Name
                </th>
                <th>
                    Description
                </th>
                <th>
                </th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>
                    <a id="new-row" href="#">New Row</a>
                </td>
                <td colspan="2">
                </td>
            </tr>
            @if (Model != null) {
                foreach (var item in Model.Attributes) {
                    <tr>
                        @Html.HiddenFor(b => item.Id)
                        @Html.HiddenFor(b => item.IdData)
                        <td class="name">@Html.TextBoxFor(b => item.Name)
                        </td>
                        <td class="description">@Html.TextBoxFor(b => item.Description)
                        </td>
                        <td>
                            <a class="delete" href="#">Delete</a>
                        </td>
                    </tr>
                }
            }
        </tbody>
    </table>
    <input type="submit" value="submit" />
}

问题是这样的。

发布时如何让 EntityFramework 识别控制器上的 DataAttributes 列表?

这是我现在正在使用的代码。

    [HttpPost]
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(Data model)
    {
        if (model != null) {

            db.Data.Add(model); //model has the model.Attributes list set as null
            db.SaveChanges();

            return View("Index", db.Data.OrderBy(a => a.Id).ToList());
        }
        return View();
    }

先感谢您。

4

2 回答 2

0

首先,您需要了解几件事。第一个问题是,为什么要先编码?您没有理由不使用 EF 工具构建 sql 模型和导入。然后,您需要了解 ModelBinder 机制是如何工作的。您发送一个带有参数的 http post 请求,每个参数都有一个名称,并希望将其绑定到模型类。ModelBinder 试图在 Model 类中找到这些名称,如果您有大量同名的参数,这将永远不会发生。这种属性也称为导航属性,它们应该由 EF 加载或以单独的形式加载。

例如,您正在尝试使用 ONE 表单来构建具有许多 DataAttributes 的 Data 对象。为什么不先创建 Data 对象,然后在另一个视图中添加 DataAttibutes?这就是 MVC 的全部意义所在。不同的模型 -> 不同的控制器 -> 不同的视图。

如果你不分开责任,你会遇到更多的麻烦。

于 2013-04-30T02:11:06.623 回答
0

为了解决这个问题,我做了以下事情:将视图上的 foreach 更改为 for 并使用 Attributes[i] 代替,以便它使用它来创建输入(这就是使控制器实际接收值的原因),我也改变了创建新行的方式,以便它们也使用相同的命名约定并传递给控制器​​。

这是新视图:

@model MVCTestApp.Models.Data
@{
    ViewBag.Title = "Edit";
}
@section Scripts {
    <script type="text/javascript">
        $(function () {
            $('#new-row').click(function () {
                var counter = $("#counter").val();
                counter++;
                $('table tbody').append(
                    '<tr>' +
                    '<td><input id="Attributes_' + counter + '__Name" ' +
                    'name="Attributes[' + counter + '].Name" type="text" /></td>' +
                    '<td><input id="Attributes_' + counter + '__Description" ' +
                    'name="Attributes[' + counter + '].Description" type="text" /></td>' +
                    '<td><a class="delete" href="#">Delete</a></td>' +
                    '</tr>'
                );
                $('.delete').click(function () {
                    $(this).parent().parent().remove();
                });
                $("#counter").val(counter);
            });
        });
    </script>
}
@using (@Html.BeginForm("Edit", "Data", FormMethod.Post)) {
    var counter = 0;
    @Html.HiddenFor(a => a.Id)
Name:
    <br />
    @Html.TextBoxFor(a => a.Name)
    <br />
Description:
    <br />
    @Html.TextBoxFor(a => a.Description)
    <br />
Code:
    <br />
    @Html.TextBoxFor(a => a.Code)
    <br />
    <table>
        <thead>
            <tr>
                <th>
                    Name
                </th>
                <th>
                    Description
                </th>
                <th>
                </th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>
                    <a id="new-row" href="#">New Row</a>
                </td>
                <td colspan="2">
                </td>
            </tr>
            @if (Model != null) {
                for (int i = 0; i < Model.Attributes.Count; i++) {
                    <tr>
                        @Html.HiddenFor(a => a.Attributes[i].Id)
                        @Html.HiddenFor(a => a.Attributes[i].IdData)
                        <td>@Html.TextBoxFor(a => a.Attributes[i].Name)</td>
                        <td>@Html.TextBoxFor(a => a.Attributes[i].Description)</td>
                        <td>
                            <a class="delete" href="#">Delete</a>
                        </td>
                    </tr>
                    counter = i;
                }
            }
        </tbody>
    </table>
    <input type="submit" value="submit" />
    @Html.Hidden("counter", counter.ToString());
}
于 2013-04-30T17:36:13.940 回答