【问题标题】:How can you create a label from one table and store the value in another with ASP.NET MVC如何使用 ASP.NET MVC 从一个表创建标签并将值存储在另一个表中
【发布时间】:2012-12-07 16:06:50
【问题描述】:

我的数据库中有一个名为 Field 的表和一个名为 FieldValue 的表。我的模型如下所示:

[Table("Field")]
public class Field
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int FieldId { get; set; }
    public string Value { get; set; }
}

[Table("FieldValue")]
public class FieldValue
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int FieldValueId { get; set; }
    public int FieldId { get; set; }
    public string Value { get; set; }
}

我想将每个字段显示为标签,然后为与该字段关联的每个 FieldValue 显示一个文本框,但我不太确定如何处理。如果这很重要,我正在使用 MVC 4。

【问题讨论】:

  • 请问您为什么选择这种结构?顺便说一句,您对问题的表述似乎是字段和值之间存在 1-1 关系?
  • 你问了一个很好的问题,我只是不想让问题太长,我的表格实际上缺少一些列,但我现在保持简单。我正在使用字段构建一个页面,我可以有多个具有相同字段的页面,但显然值可以不同

标签: asp.net-mvc entity-framework asp.net-mvc-4 asp.net-mvc-views


【解决方案1】:

您可以将连接的数组返回到视图模型类(未经语法/错别字测试):

public class ViewModel
{
    public KeyValuePair<string,string> Fields { get; set; }
}

var kvps = Fields.Join(FieldValues,
    f => f.FieldId,
    fv => fv.FieldId,
    (f, fv) => 
        new KeyValuePair<string,object>(f.Value, fv.Value)
    }).ToArray();
var viewModel = new ViewModel { Fields = kvps };

return View(viewModel);

然后在视图中,简单地遍历值:

@model MyNamespace.ViewModel

@foreach (var kvp in Model.Fields)
{
    <span class="field-label">@kvp.Key</span>
    <span class="field-value">@Html.TextBoxFor(_ => kvp.Value)</span>
}

如果你把它放在一个表单中,那么回发也应该能正常工作(因为它使用TextBoxFor)。

【讨论】:

  • 这似乎是正确的答案。唯一的问题是我得到一个异常,上面写着“LINQ to Entities 仅支持无参数构造函数和初始化程序”。我认为这与 KeyValuePair 有关,但想知道您是否知道解决方法。
  • 正确查询:var kvps = (from f in FieldDb.Field join fv in FieldDb.FieldValue on f.FieldId equals fv.FieldId into JoinedFieldId from fv in JoinedFieldId.DefaultIfEmpty() select new { Key = f.FieldId, Value = fv.Value }).ToList().Select(x=&gt;new KeyValuePair&lt;int, string&gt;(x.Key, x.Value)); 你走对了。
【解决方案2】:

不确定您要做什么,我不想做任何假设,但我感觉您可能走错了路。您可能知道的 MVC 具有强类型视图,因此您可以将视图“绑定”到有用的业务对象(例如 Person),然后使用类似的东西生成 HTML

Html.TextBoxFor(p => p.Name)

其中 p 是一个人

您尝试构建的东西似乎是实现此目的的技巧。您不能只创建有意义的对象来保存您的信息,然后将它们传递给强类型视图吗?如果另一个页面具有相同的字段,则传递相同的对象。

【讨论】:

  • 我知道带有 razor 的 HTML 助手。我知道怎么做@Html.DisplayFor(f =&gt; f.Value)Html.TextBoxFor(f =&gt; f.Value),但我不知道怎么做@HTML.DisplayFor(f =&gt; f.Value)Html.TextBoxFor(fv =&gt; fv.Value)。我真的不知道如何将所有这些传递给视图
  • 不确定我是否明白这一点,如果您出于某种原因想将 f 和 fv 都传递给视图,那么为什么不将它们包装在一个新对象“wrap”中并执行 HTML.DisplayFor(wrap => wrap.f.Value) 和 Html.TextBoxFor(wrap => wrap.fv.Value)。我看不出这怎么可能
【解决方案3】:

这里的答案取决于你是否知道你有多少字段。

如果你这样做了,那么你应该创建一个强类型模型来绑定你的 mvc 视图,并使用如下数据注释:

public class MyModel
{
    [Display(Name="Field name 1")
    public string Field1 { get; set; }

    [Display(Name="Field name 2")
    public string Field2 { get; set; }
}

那么在你看来你可以使用下面的代码:

@Html.LabelFor(model => model.Field1)
@Html.TextBoxFor(model => model.Field1)

@Html.LabelFor(model => model.Field1)
@Html.TextBoxFor(model => model.Field1)

但是,如果您不知道前面的字段数量,因此无法填充这样的强类型模型,那么我建议您执行以下操作:

  • 向字段添加导航属性,以便您可以轻松获取值
  • 编写一些代码在数据库之间映射到可能的字典
  • 在您的视图中编写一个循环并像这样使用老式的 html 助手:

...

@for (var key in model.FieldDictionary.Keys)
{
    @Html.Label("key", model.FieldDictionary(key))
    @Html.TextBox(model.FieldDictionary(key))
}

请注意,此代码未经测试,在第二个示例中,您必须弄清楚如何在发布表单时重新获取数据,但希望能给您一个起点。

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-31
    • 1970-01-01
    • 1970-01-01
    • 2017-09-24
    • 1970-01-01
    • 2019-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多