【问题标题】:Multiple Checkboxes to select and save values in database table C# MVC3用于在数据库表 C# MVC3 中选择和保存值的多个复选框
【发布时间】:2012-08-03 03:37:15
【问题描述】:

我正在进行的项目要求我在表单上放置复选框,以便用户可能选择多个项目。我可以将这些作为布尔值放在单独的列中,但复选框值可能会更改或需要添加。所以我创建了一个包含这些复选框名称的表格,然后将它们列出来。我的问题是;我如何将这些值放入与客户一致的另一个表中。这应该如何正确处理?

视图具有公司名称和记录 ID /AuditSchedule/details/208 我已经读到在列中放置多个值不是一个好习惯,但我还有什么其他选择?

非常感谢!

我的客户表有一个 ProductType 字段。这与任何事情无关。还有另一个包含产品类型的表格,我想将其列为复选框。我在这两个表之间没有任何关系。对我来说似乎不应该有,但请纠正我,让我知道是否应该有。 So when a check box is selected i want that value (ProductName) to be put in the customer table in the ProductType field separated with commas.

这是客户或日程表:

    public class AuditSchedule
{
    public virtual int AuditScheduleID { get; set; }
    public virtual Nullable<DateTime> audit_completed_date { get; set; }
    public virtual string gl_cmp_key { get; set; }
    public virtual string audit_year { get; set; }
    public virtual string ar_ship_key { get; set; }
    public virtual string ar_ship_name { get; set; }
    public virtual string im_adres_city { get; set; }
    public virtual string im_adres_state { get; set; }
    public virtual string audit_type { get; set; }
    public virtual string audit_no { get; set; }
    public virtual string audit_group { get; set; }
    public virtual string Footage { get; set; }
    public virtual string Rolling3MosFootage { get; set; }
    public virtual string snp_SalesRep8 { get; set; }
    public virtual string epg_sales_rep_accountable { get; set; }
    public virtual string tech_service_rep { get; set; }
    public virtual string audit_done_by { get; set; }
    public virtual Nullable<DateTime> audit_recieved_date { get; set; }
    public virtual string audit_notes { get; set; }
    public virtual string audit_pdf { get; set; }
    public virtual string updated { get; set; }
    public virtual string hidden { get; set; }
    public virtual string en_stats_key { get; set; }
    public virtual string Control_ID { get; set; }
    public virtual Nullable<DateTime> audit_date { get; set; }
    public virtual string contacts_present { get; set; }
    public virtual string audit_furnished_to { get; set; }
    public virtual string spacer_type { get; set; }
}

这是产品表:

    public class SpacerProduct
{
    public int SpacerProductID { get; set; }
    public string SpacerBrand { get; set; }
    public string SpacerName { get; set; }
}

希望对你有帮助

视图是 AuditSchedules 的表单类型编辑,只有几个地方需要填写。这部分有效。将复选框添加到视图是我迷路的地方。我创建了一个填充复选框的 ToList 的局部视图,然后将其添加到表单中。不知道如何得到表格中的结果。

关于 Tohid 的问题: 我对一些事情有疑问。首先是 ViewModel,我假设这只是你的 Models 目录的命名空间,而我的只是 Models。 _db.getAuditScheduleById 不在我的实体中,您解释说我可能必须采取另一种方式。对我来说它将是 _db.AuditSchedules 它出现在下拉列表中但不喜欢它所以我将其更改为 2012 年 7 月 2 日更新 viewModel.AuditScheduleInstance = _db.AuditSchedules.Single(r => r.AuditScheduleID == id);

我的问题仍然存在

_db.GetAvailableSpacerProducts()

我的实体中没有任何反映这一点的东西,我不知道如何更改它。可能类似于我在另一个中所做的更改,但不确定。

2012 年 7 月 5 日更新

这里是QQAEntities:

命名空间 QQAForm.Models

{
public class QQAEntities : DbContext
   {
    public DbSet<AuditSchedule> AuditSchedules { get; set; }
    public DbSet<Category> Categories { get; set; }
    public DbSet<SubCategory> SubCategories { get; set; }
    public DbSet<MainQuestion> MainQuestions { get; set; }
    public DbSet<Suggestion> Suggestions { get; set; }        
    public DbSet<DocumentLink> DocumentLinks { get; set; }
    public DbSet<Audit> Audits { get; set; }
    public DbSet<AuditData> AuditDatas { get; set; }
    public DbSet<SpacerProduct> SpacerProducts { get; set; }
    public DbSet<ScoreCard> ScoreCards { get; set; }



   }
}

我的解决方案中还有另一个名为 QQAForm.Data 的项目,它仅控制与成员资格相关的所有内容的角色和安全性。 希望这可以帮助。 感谢您的时间和耐心。

2012 年 7 月 6 日更新

最终工作编辑:

    [HttpPost]
    public ActionResult Edit(AuditScheduleEdit viewModel)
    {            
        if (ModelState.IsValid)
        {
            viewModel.PopulateCheckBoxsToSpacerType();
            _db.Entry(viewModel.AuditScheduleInstance).State = System.Data.EntityState.Modified;
            _db.SaveChanges();
            return RedirectToAction("Index");
        }
        else
        {
            return View(viewModel);
        }

    }

2012 年 8 月 2 日更新

我已经决定我可以在这个项目的其他领域使用它。我有多个使用复选框的地方。

我试图在另一个视图上实现它,但它不起作用。它不起作用的原因是因为为了填充复选框,它会查看当前表中的 ID,以便可以更新它。这是sn-p:

        //get
    public ActionResult _Forms(int id)
    {
        AuditFormEdit viewModel = new AuditFormEdit();
        viewModel.ScoreInstance = _db.MainAnswers.Single(r => r.MainAnswerID == id);
        viewModel.InitializeScoreCheckBoxHelperList(_db.Scores.ToList());
        return View(viewModel);
    }

    //post
    [HttpPost]
    public ActionResult _Forms(int id, AuditFormEdit viewModel)
    {
        if (ModelState.IsValid)
        {
            viewModel.PopulateCheckBoxsToScores();
            _db.Entry(viewModel.ScoreInstance).State = System.Data.EntityState.Modified;
            _db.SaveChanges();
            return RedirectToAction("/");
        }
        else
        {
            return View(viewModel);
        }
    }

(r => r.MainAnswerID == id) 是问题所在。 MainAnswer 是需要更新的表。该记录还应插入 AuditScheduleID、MainQuestionID 和从 Score 复选框填充的文本。如果我对此发表评论,我将一无所获。我真正需要的是一种方法来接受这个并用数据插入一条新记录。 不知道如何更改代码来执行此操作。

【问题讨论】:

  • 你有数据库表模式和关系吗?你能和我们分享一下吗?
  • 我很乐意分享任何需要的东西。但是,我已将其建立在代码优先的方法上。我不确定如何在不输入整个内容的情况下与您共享架构。如果有办法产生这个我会做 - 但需要帮助。例如,我开始使用 DBEntities,它创建了一个很好的表视图。我不知道如何用这种方法做到这一点
  • 因此,如果您共享模型类及其重要属性就足够了。
  • 重要的属性是 spacer_type 将从 SpacerName 中获取值。因此,如果用户选择 2 个 SpacerName,它们将显示在 spacer_type (product1, product3) 列中,依此类推。
  • 尝试使用包含此项的键值对的字典。

标签: c# asp.net-mvc-3 checkbox


【解决方案1】:

如果我理解正确,您是在说:

  1. Customer 类有一个名为 ProductTypestring 属性,其中包含以逗号分隔的 ProductType 名称字符串。
  2. ProductType有一个string属性ProductName
  3. 在视图中,任何 ProductType 都显示为复选框,可以为每个客户选择/取消选择。

对吗?对我来说,这似乎是一种多对多关系

你读过MVC教程的这一章:Getting Started with EF using MVC吗?尤其是这部分:Creating a More Complex Data Model for an ASP.NET MVC Application

对我来说,如果您将 Customer.ProductType 的类型从 string 更改为 List&lt;ProductType&gt;,它可以解决所有问题。

但是,通过将 Customer.ProductType 保持为 string ,仍然可以解决。

代码

根据AuditScheduleSpacerProduct类(模型),我开发了一个新的VeiwModel类。将 ViewModel 视为一个容器,它打包其他类并准备好将它们发送到 View。

namespace MvcApplication1.ViewModels
{
    public class AuditScheduleEdit
    {
        public Models.AuditSchedule AuditScheduleInstance { get; set; }

        public List<SpacerProductCheckBoxHelper> SpacerProductCheckBoxHelperList { get; set; }

        public void InitializeSpacerProductCheckBoxHelperList(List<Models.SpacerProduct> SpacerProductList)
        {
            if (this.SpacerProductCheckBoxHelperList == null)
                this.SpacerProductCheckBoxHelperList = new List<SpacerProductCheckBoxHelper>();

            if (SpacerProductList != null
                && this.AuditScheduleInstance != null)
            {
                this.SpacerProductCheckBoxHelperList.Clear();
                SpacerProductCheckBoxHelper spacerProductCheckBoxHelper;
                string spacerTypes =
                    string.IsNullOrEmpty(this.AuditScheduleInstance.spacer_type) ?
                    string.Empty : this.AuditScheduleInstance.spacer_type;
                foreach (Models.SpacerProduct spacerProduct in SpacerProductList)
                {
                    spacerProductCheckBoxHelper = new SpacerProductCheckBoxHelper(spacerProduct);
                    if (spacerTypes.Contains(spacerProduct.SpacerName))
                        spacerProductCheckBoxHelper.Checked = true;
                    this.SpacerProductCheckBoxHelperList.Add(spacerProductCheckBoxHelper);
                }
            }
        }

        public void PopulateCheckBoxsToSpacerType()
        {
            this.AuditScheduleInstance.spacer_type = string.Empty;
            var spacerTypes = this.SpacerProductCheckBoxHelperList.Where(x => x.Checked)
                                  .Select<SpacerProductCheckBoxHelper, string>(x => x.SpacerName)
                                  .AsEnumerable();
            this.AuditScheduleInstance.spacer_type = string.Join(", ", spacerTypes);
        }

        public class SpacerProductCheckBoxHelper : Models.SpacerProduct
        {
            public bool Checked { get; set; }

            public SpacerProductCheckBoxHelper() : base() { }

            public SpacerProductCheckBoxHelper(Models.SpacerProduct spacerProduct)
            {
                this.SpacerProductID = spacerProduct.SpacerProductID;
                this.SpacerName = spacerProduct.SpacerName;
                this.SpacerBrand = spacerProduct.SpacerBrand;
            }
        }
    }
}

所以这里是相关Controller的Edit方法:

    public ActionResult Edit(int id)
    {
        AuditScheduleEdit viewModel = new AuditScheduleEdit();
        viewModel.AuditScheduleInstance = _db.GetAuditScheduleById(id);
        viewModel.InitializeSpacerProductCheckBoxHelperList(_db.GetAvailableSpacerProducts());
        return View(viewModel);
    }

    [HttpPost]
    public ActionResult Edit(AuditScheduleEdit viewModel)
    {
        if(ModelState.IsValid)
        {
            viewModel.PopulateCheckBoxsToSpacerType();
            // TODO: Add update logic here
            return RedirectToAction("Index");
        }
        else
        {
            return View(viewModel);
        }
    }

在第一个操作 (HttpGET) 中,我只是构造了一个 AuditScheduleEdit 的实例,然后从我的数据库 (_db.GetAuditScheduleById(id)) 中分配请求的 AuditSchedule(您可能有不同的方式从存储库中查询数据)。

然后必须将SpacerProducts 的集合传递给InitializeSpacerProductCheckBoxHelperList() 函数(对不起,因为名字很长,尽量清晰易懂!)。此函数创建一个SpacerProductCheckBoxHelper 列表,用于在视图上生成复选框。

当用户提交表单时,AuditScheduleEdit 被重新创建(基于表单数据)并将被发送到第二个编辑操作(HttpPost)。在那里,PopulateCheckBoxsToSpacerType() 将选中的复选框列表转换为逗号分隔的字符串并将其分配给AuditSchedule.spacer_type

这是视图:

@model MvcApplication1.ViewModels.AuditScheduleEdit
@using (Html.BeginForm())
{
    <div>
        <h3>Audi Schedule</h3>
        @Html.LabelFor(m => m.AuditScheduleInstance.AuditScheduleID)
        @Html.DisplayFor(m => m.AuditScheduleInstance.AuditScheduleID)
        @Html.HiddenFor(m => m.AuditScheduleInstance.AuditScheduleID)
        <br />
        @Html.LabelFor(m => m.AuditScheduleInstance.Control_ID)
        @Html.EditorFor(m => m.AuditScheduleInstance.Control_ID)
        // Here, add any field of AuditSchedule which needs to show on edit form 
        //       like what I did for AuditScheduleID and Control_ID.
        <h3>SpacerType</h3>
        @for (int index = 0; index < Model.SpacerProductCheckBoxHelperList.Count; index++)
        {
            @Html.CheckBoxFor(m => m.SpacerProductCheckBoxHelperList[index].Checked)
            @Html.LabelFor(m => m.SpacerProductCheckBoxHelperList[index], Model.SpacerProductCheckBoxHelperList[index].SpacerName)
            @Html.HiddenFor(m => m.SpacerProductCheckBoxHelperList[index].SpacerProductID)
            @Html.HiddenFor(m => m.SpacerProductCheckBoxHelperList[index].SpacerName)
            <br />
        }
    </div>
    <div>
        <input type="submit" value="Save" />
    </div>
}

我在 Visual Studio developer 2010 Exp 中编写了这段代码,它运行良好。 You can download this code from here.

【讨论】:

  • 感谢您的回复。是的,如果你能举一个很好的例子。此外,视图显示复选框,因为 ToList 不确定这是正确的做法。我也看到了几个如何显示的例子。有一个@Html.checkbox,也可以从 完成。什么是最好的?上面的示例显示了两个表的类。客户实际上是 AuditSchedule,使用 spacer_type 存储逗号分隔值,产品类型是 SpacerProduct 类,并使用具有复选框值的 SpacerName。
  • 好的。知道了。我给你拍个样品。同时我建议你去asp.net/mvc观看右栏的所有视频,尤其是论文2:1.pluralsight-training.net/microsoft/players/…; 2.pluralsight-training.net/microsoft/players/…
  • 感谢您提供样品。我已将您的代码放入我的项目中。我已经用问题更新了我的帖子,因为评论太长了。
  • 我已将代码更改为读取 viewModel.InitializeSpacerProductCheckBoxHelperList(_db.SpacerProducts.ToList());这似乎工作。但是,它不想保存任何更改。我更改了代码并添加了 _db.SaveChanges();但我似乎记得我之前可以保存它的唯一方法是使用(int id,FormCollection 集合)。这不适用于当前代码。
  • @user656107 ;你快到了,我的朋友。当用户提交表单并且应用程序正在路由到[HttpPost] Edit action 时,在执行viewModel.PopulateCheckBoxsToSpacerType(); 之后,您需要的所有内容都在viewModel.AuditScheduleInstance 中并且可以保存。现在由您来更改您的存储库save() 方法以接受Models.AuditSchedule 的实例作为参数并将其放入数据库。您之前的保存方法(需要 idFormCollection)不再有用了。
【解决方案2】:

我不清楚您提出的问题,但我认为您需要更新 当复选框值存储在您创建的表中时,您在表(视图)中的记录。我认为不需要更新您的表,您只需要创建一个关系 在两个表之间,然后您可以在内部查询和连接的帮助下获取所有日期。

但如果您仍然需要更新您的表,您可以在您创建的表中使用“插入后”触发器。 如果您也可以共享表结构,那将非常有帮助。

您需要再创建一个表(以存储 itemselected 和选择它的客户的关系) 与列 (AuditScheduleID int,SpacerType int) 该表应该在两个列上都有复合键 和 1) 列 AuditScheduleID 应该与 Customer 表有外键关系 2) 列 SpacerType 应该与 Product 表有外键关系。 3)当客户选择多个产品并提交每个产品的信息和 AuditScheduleID 应该在上面创建的表中保存为不同的行。

现在您可以通过完全标准化以这种方式存储数据

【讨论】:

  • 不会有任何关系。产品表仅列出产品。产品不是此表中的列。这会更容易,但是如果有新产品,则必须将其添加为复选框。显示带有复选框的产品很容易,当他们选中复选框时 - 将产品名称保存在 Products 下的客户表中。
猜你喜欢
  • 1970-01-01
  • 2016-04-08
  • 2018-11-26
  • 1970-01-01
  • 2021-12-07
  • 2013-01-06
  • 2015-10-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多