【问题标题】:Using many to many relationship in ASP.net在 ASP.net 中使用多对多关系
【发布时间】:2017-04-12 09:28:15
【问题描述】:

我正在尝试使用多对多关系,我成功地编辑和显示了一个客户(我的代码上的名称为“客户”),但我无法创建。 在我的示例中,一个客户(客户)可以是一个或多个社团的一部分。 逐步使用 Visual Studio,我注意到我的值无法传递给我的第一个“创建”函数到第二个。我成功地获得了我想要的领域,但无法发布它们。 我的客户端控制器:

public ActionResult Create()
    {
        var cli = new ClientViewModel
        {
            Client = new Client()

        };

        var allSocietesList = db.Societes.ToList();

cli.AllSocietes = allSocietesList.Select(o => new SelectListItem
        {
            Text = o.Nom,
            Value = o.ID.ToString()
        });

        ViewBag.StatutClientID = new SelectList(db.StatutClients, "ID", "Designation");
        return View(cli);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(ClientViewModel client) //Here is where the value dosesn't pass, "client" value is null;
    {
        if (ModelState.IsValid)
        {

            var cliToAdd = new Client();
            var updatedSocietes = new HashSet<int>(client.SelectedSociete);
            foreach (Societe societe in db.Societes)
            {
                if (updatedSocietes.Contains(societe.ID))
                {
                    cliToAdd.Societes.Add((societe));
                }

            }
            db.Clients.Add(cliToAdd);
            db.Entry(cliToAdd).State = System.Data.Entity.EntityState.Added;

            db.SaveChanges();


            return RedirectToAction("Index");
        }
        ViewBag.StatutClientID = new SelectList(db.StatutClients, "ID", "Designation", client.Client.StatutClientID);
            return View(client);

}

现在是我的客户端模型:

namespace CRM.Models
{
public class Client : Personne // Héritage de la classe Personne
{
    public Client()
    {
        this.Societes= new HashSet<Societe>();
    }

    [Column("StatutClientID")]

    public int StatutClientID { get; set; }

    public string Fonction { get; set; } // TODO:Type enum

    [Display(Name = "Est Actif ?")]
    public bool IsActif { get; set; }

    [DataType(DataType.MultilineText)]
    public string Commentaire { get; set; }

    public string Fax { get; set; }

    public virtual StatutClient StatutClient { get; set; }

    public virtual ICollection<Societe> Societes { get; set; }
    override public string ToString()
    {
        return this.Prenom+" "+this.Nom;
    }

   }

  }    

我在控制器中使用的类 ViewModel:

namespace CRM.ViewModels
{
public class ClientViewModel
{
    public Client Client { get; set; }
    public IEnumerable<SelectListItem> AllSocietes { get; set; }

    private List<int> selectedSociete;
    public List<int> SelectedSociete
    {
        get
        {
            if (selectedSociete == null)
            {
                selectedSociete = Client.Societes.Select(m => m.ID).ToList();
            }
            return selectedSociete;
        }
        set { selectedSociete = value; }
    }
}
}

最后,我的观点:

@model CRM.ViewModels.ClientViewModel

@{
ViewBag.Title = "Create";
}

<h2>Create</h2>


@using (Html.BeginForm())
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
    <h4>Client</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })

    <div class="form-group">
        @Html.LabelFor(model => model.Client.Nom, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Client.Nom, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Client.Nom, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Client.Prenom, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Client.Prenom, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Client.Prenom, "", new { @class = "text-danger" })
        </div>
    </div>


    <div class="form-group">
        @Html.LabelFor(model => model.Client.Fonction, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Client.Fonction, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Client.Fonction, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Client.Commentaire, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Client.Commentaire, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Client.Commentaire, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Client.Telephone, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Client.Telephone, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Client.Telephone, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Client.Mobile, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Client.Mobile, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Client.Mobile, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Client.Fax, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Client.Fax, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Client.Fax, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Client.Mail, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Client.Mail, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Client.Mail, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Client.IsActif, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            <div class="checkbox">
                @Html.EditorFor(model => model.Client.IsActif)
                @Html.ValidationMessageFor(model => model.Client.IsActif, "", new { @class = "text-danger" })
            </div>
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Client.StatutClientID, "StatutClient", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownList("StatutClientID", null, htmlAttributes: new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.Client.StatutClientID, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.AllSocietes, "JobTag", new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.ListBoxFor(model => model.SelectedSociete,     Model.AllSocietes)
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
</div>
}

<div>
@Html.ActionLink("Retour à la liste", "Index")
</div>

@section Scripts {
@System.Web.Optimization.Scripts.Render("~/bundles/jqueryval")
}

(我的社团模型(名称“societe”),如果你想知道上面有什么,但问题不是来自这里,你可以跳过它)。

namespace CRM.Models
{
public class Societe
{
    public Societe()
    {
        this.Clients = new HashSet<Client>();
    }
    public int ID { get; set; }
    public string Nom { get; set; }
    //[Required] //TODO: renseigner adresse dans les societes de    l'initializer
    [Display(Name = "Lieu")]
    public int LieuID { get; set; }
    public string Adresse { get; set; }
    public int Km { get; set; }
    public string Temps { get; set; }
    public bool IsActif { get; set; }
    public virtual Lieu Lieu { get; set; }
    public virtual ICollection<Affaire> Affaires { get; set; }
    public virtual ICollection<Client> Clients { get; set; }

}
}

为了成功编辑和显示,我遵循了该教程: https://www.codeproject.com/articles/702890/mvc-entity-framework-and-many-to-many-relation

如果我的问题因为我的英语或其他原因而难以理解,请询问:)

编辑:这是我的编辑功能,它是 100% 功能性的:

    public ActionResult Edit(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        var clientViewModel = new ClientViewModel
        {
            Client = db.Clients.Include(i => i.Societes).First(i => i.ID ==  id)
        };

        if (clientViewModel.Client == null)
            return HttpNotFound();
        var allSocietesList = db.Societes.ToList();

        clientViewModel.AllSocietes = allSocietesList.Select(o => new  SelectListItem
        {
            Text = o.Nom,
            Value = o.ID.ToString()
        });


        ViewBag.StatutClientID = new SelectList(db.StatutClients, "ID", "Designation", clientViewModel.Client.StatutClientID);
        return View(clientViewModel);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(ClientViewModel clientView)
    {

        if (clientView == null) return new HttpStatusCodeResult(HttpStatusCode.BadRequest);



        if (ModelState.IsValid)
        {
            var clientToUpdate = db.Clients
                .Include(i => i.Societes).First(i => i.ID == clientView.Client.ID);

            if (TryUpdateModel(clientToUpdate, "Client", new string[] { "Fonction", "Commentaire", "Nom", "Prenom", "Telephone", "Mobile", "Fax", "Mail", "IsActif", "StatutClientID" }))
            {
              //  var newJobTags = db.Societes.Where(
                //    m => clientView.SelectedSociete.Contains(m.ID)).ToList();
                var updatedSocietes = new HashSet<int>(clientView.SelectedSociete);
                foreach (Societe societe in db.Societes)
                {
                    if (!updatedSocietes.Contains(societe.ID))
                    {
                        clientToUpdate.Societes.Remove(societe);
                    }
                    else
                    {
                        clientToUpdate.Societes.Add((societe));
                    }
                }

                db.Entry(clientToUpdate).State = System.Data.Entity.EntityState.Modified;
                db.SaveChanges();
            }

            return RedirectToAction("Index");
        }
        ViewBag.StatutClientID = new SelectList(db.StatutClients, "ID", "Designation", clientView.Client.StatutClientID);
        return View(clientView);
    }

与编辑视图相关联:

  @model CRM.ViewModels.ClientViewModel

@{
ViewBag.Title = "Edit";
}

<h2 class="well">Clients - Edit</h2>

@using (Html.BeginForm())
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    @Html.HiddenFor(model => model.Client.ID)

    <div class="form-group">
        @Html.LabelFor(model => model.Client.Fonction, htmlAttributes: new {  @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Client.Fonction, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Client.Fonction, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Client.Commentaire, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Client.Commentaire, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Client.Commentaire, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Client.Nom, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Client.Nom, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Client.Nom, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Client.Prenom, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Client.Prenom, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Client.Prenom, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Client.Telephone, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Client.Telephone, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Client.Telephone, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Client.Mobile, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Client.Mobile, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Client.Mobile, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Client.Fax, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Client.Fax, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Client.Fax, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Client.Mail, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Client.Mail, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Client.Mail, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Client.IsActif, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            <div class="checkbox">
                @Html.EditorFor(model => model.Client.IsActif)
                @Html.ValidationMessageFor(model => model.Client.IsActif, "", new { @class = "text-danger" })
            </div>
        </div>
    </div>


    <div class="form-group">
        @Html.LabelFor(model => model.Client.StatutClientID, "Client.StatutClientID", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownListFor(m => m.Client.StatutClientID,
                    (SelectList)ViewBag.StatutClientID,
                    Model.Client.StatutClient.ID);

            @*Html.DropDownList("Client.StatutClientID", null, htmlAttributes: new { @class = "form-control" })*@
            @Html.ValidationMessageFor(model => model.Client.StatutClientID, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.AllSocietes, "JobTag", new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.ListBoxFor(m => m.SelectedSociete, Model.AllSocietes)
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Save" class="btn btn-default" />
        </div>
    </div>
</div>
}

<div>
@Html.ActionLink("Retour à la liste", "Index")
</div>

@section Scripts {
@System.Web.Optimization.Scripts.Render("~/bundles/jqueryval")
}

【问题讨论】:

  • 您是否将需求代码添加到您的数据库上下文中?如:protected override void OnModelCreating(DbModelBuilder modelBuilder) { ... } 见msdn.microsoft.com/en-us/library/jj591620(v=vs.113).aspx《配置多对多关系》
  • 您好,感谢您的回答。不,我没有这样做,我的代码首先是“数据库”,并且编辑是功能性的,只有在我使用编辑时,我才能为一个客户添加我想要的尽可能多的社会......
  • 实体不应该自动创建联结表吗???
  • 是的,这是可能的,但我首先创建了联结表,然后更新了我的代码。
  • 这……有点奇怪,我不知道这是不是个好主意。帮不上忙。

标签: c# asp.net-mvc entity-framework many-to-many


【解决方案1】:

我能看到的唯一问题是你的观点,其余的对我来说都还可以。

首先,我经常指定表单的发布方式和位置

@using (Html.BeginForm("Action_name", "Controler_name", FormMethod.Post, new { role = "form" }))
{
}

然后,您还应该将模型的 id 放在页面中。这是我现在总是做的事情。它更加连贯。如果您跳过该部分,您的 id 将不可用,该页面是防止其消失的唯一方法。

类似:

@Html.HiddenFor(t => t.client.id)

将这些用于您希望在不显示的情况下传递回表单的所有模型实例。我不知道它会完全解决您的问题,但这是一个好的开始。

【讨论】:

  • 完成!感谢您的回答,但不幸的是,问题并不明显。我的第二种方法“创造”仍然没有发挥我社会的价值......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-03
  • 2011-01-09
  • 2013-12-10
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多