首页 文章

保存并读取复选框值 - 多对多关系c#

提问于
浏览
0

在多对多关系中从表中实现读取和保存值的最佳方法是什么?对于选定的技术,我想要复选框或类似的东西 .

我有 table Question

public int Id { get; set; }
public string Name{ get; set; }
public Country Country { get; set; }
public int? CountryId { get; set; }

public ICollection<Technology> Technologies { get; set; }

Technology

public int Id { get; set; }
public string Name{ get; set; }
public ICollection<Question> Questions{ get; set; }

我创建了具有属性的ViewModel QuestionViewModel - 如果有必要,不确定

public int Id { get; set; }
public string Description { get; set; }
public IEnumerable<Technology> Technologies { get; set; } // not sure about this

保存工作没有表技术 .

也许我需要ViewModel与ICollection Technologies和ICollection Questions类而不是我当前的?

Razor页面是没有Technology类的简单形式,也不确定如何实现 . 实体框架从代码优先方法创建了表 TechnologyQuestions .

保存操作如下所示

public ActionResult Save(Question question)
{
            if (!ModelState.IsValid)
            {
                var viewModel = new QuestionViewModel
                {
                    Countries = _context.Countries.ToList()
                };
                return View("NewForm", viewModel);
            }

            if (question.Id == 0)
                _context.Questions.Add(question);
            else
            {
                var questionInDb = _context.Questions.Single(q => q.Id == question.Id);

                questionInDb.Name= question.Name;
                questionInDb.CountryId = question.CountryId;

            }

            _context.SaveChanges();

            return RedirectToAction("Index", "Home");
        }

我正在使用C#MVC 5.任何帮助或方向表示赞赏 .

2 回答

  • 0

    你没有说当你添加表技术时什么不起作用,所以我假设你的问题是EF在你将它们链接到问题时尝试插入新技术 .

    您应该首先尝试将Technology对象附加到上下文:

    if (question.Id == 0) 
    {
        foreach(var tech in question.Technologies)
            _context.Technologies.Attach(tech)
        _context.Questions.Add(question);
    }
    else
    {
        var questionInDb = _context.Questions.Single(q => q.Id == question.Id);
    
        questionInDb.Name= question.Name;
        questionInDb.CountryId = question.CountryId;
    
        foreach(var tech in question.Technologies.Where(t => !questionInDb.Technologies.Any(x => x.Id == t.Id)))
            _context.Technologies.Attach(tech);
    
        //Remove Technologies that have been unchecked in the page
        //...
    }
    
  • 0

    我解决了这个问题 .

    QuestionViewModel 具有ICollection of Technology类 .

    Save 行动中我有

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Save(Question question, string[] techIds)
    {
       UpdatePostCategories(question, techIds);
       ....
       _context.Questions.Add(question);
       _context.SaveChanges();
    }
    

    并且 UpdatePostCategories 方法看起来像这样

    private void UpdatePostCategories(Question question, string[] techIds)
    {
        var selectedCategoriesHS = new HashSet<string>(techIds);
        var postCategories = new HashSet<int>
               (question.Technologies.Select(t=> t.Id));
    
            foreach (var item in _context.Technologies)
            {
                if (selectedCategoriesHS.Contains(item.Id.ToString()))
                {
                    if (!postCategories.Contains(item.Id))
                    {
                        question.Technologies.Add(item);
                    }
                }
                else
                {
                    if (postCategories.Contains(item.Id))
                    {
                        question.Technologies.Remove(item);
                    }
                }
            }
        }
    

    在我的View复选框中,您可以选择所有技术,如下所示

    <div class="form-group">
        @foreach (var item in Model.Technologies)
        {
           <div>
             <label>@Html.DisplayFor(model => item.Name)</label>
             <input type="checkbox" value="@item.Id" name="techIds" />
           </div>
        }
    </div>
    

相关问题