Vini
Vini

Reputation: 2134

Simple approach for Adding object in a many to many relationship

I have 2 classes ConfigurationCollection and OptionValues which has a many to many relationship. I have tried solutions on the net to get it working. I tried adding another class to create two one to many relationship. But I am not understanding it the right way I suppose. And I also tried it without adding a third class.

Model classes

public class ConfigurationCollection
{
    public int ConfigurationCollectionID { get; set; }
    public string CollectionName { get; set; }
    public int LsystemID { get; set; }

    public virtual Lsystem Lsystem { get; set; }
    public virtual ICollection<OptionValue> OptionValues { get; set; }
}
public class OptionValue
{
    public int OptionValueID { get; set; }
    public string OptionVal { get; set; }
    public int OptionID { get; set; }

    public virtual ICollection<ConfigurationCollection> ConfigurationCollections { get; set; }
    public virtual Option Option { get; set; }
}
public class Config_OptionVal
{
    public int Config_OptionValID { get; set; }
    public int OptionValueID { get; set; }
    public int ConfigurationCollectionID { get; set; }
    public bool OptionValChecked { get; set; }

    public virtual OptionValue OptionValue { get; set; }
    public virtual ConfigurationCollection ConfigurationCollection { get; set; }
}

Controller

 public ActionResult Create(int LsystemID)
 {
     var model = new ConfigurationCollection
     {
       LsystemID = LsystemID,
       Lsystem = db.Lsystem.FirstOrDefault(x => x.LsystemID == LsystemID),
       OptionValues=new List<OptionValue>()
     };
     return View(model);
 }

I am not sure what should be written in the Controller. I am able to populate the OptionValues in my View. I am just missing something that could save the data into the database.

UPDATE : Create Post Action Method

public ActionResult Create(ConfigurationCollection con)
{
    foreach(var item in con.OptionValues)
    {
         if(item.OptionValueChecked)
            db.Config_OptionVal.Add(item);
    }
    db.ConfigurationCollection.Add(con);
    db.SaveChanges();
}

Update : View

@using (Html.BeginForm()) 
{
   @Html.AntiForgeryToken()
   @Html.LabelFor(model => model.CollectionName, htmlAttributes: new { @class = "control-label col-md-2" })
   @Html.EditorFor(model => model.CollectionName, new { htmlAttributes = new { @class = "form-control" } })

    <table class="table">
    <tr style="column-width:20px">
         <th>Option</th>
         <th>Option value</th>
    </tr>
    @foreach (var item in Model.Lsystem.Options)
    {
       <tr>
       <td><b>@item.OptionName</b></td>
       <td>                        
       @foreach (var ov in item.OptionValues)
       {                        
         <input type="checkbox"  id="OptionValues"/>@ov.OptionVal
       }
       </td>
       </tr>
     }
     </table>
     <input type="submit" value="Create" class="btn btn-default" />
}

Upvotes: 0

Views: 171

Answers (1)

Fabio
Fabio

Reputation: 11990

In your case, the third table is not mandatory.

public class ConfigurationCollection
{
    public int ConfigurationCollectionID { get; set; }
    public string CollectionName { get; set; }

    public virtual ICollection<OptionValue> OptionValues { get; set; }
}
public class OptionValue
{
    public int OptionValueID { get; set; }
    public string OptionVal { get; set; }

    public virtual ICollection<ConfigurationCollection> ConfigurationCollections { get; set; }
}

The EF will recognize the n-m relationship.

In the Create method, you are sending a ConfigurationCollection object to the Controller, right? So, you just have to insert the object into the DbSet. Like this:

public ActionResult Create(ConfigurationCollection con)
{
    db.ConfigurationCollection.Add(con);
    //all of the OptionValues inside the 'con' object will be automatically inserted
    db.SaveChanges();
}

EDIT

public ActionResult Create(ConfigurationCollection con, int[] optionsValuesIds)
{
    db.ConfigurationCollection.Add(con);
    foreach (optionValueId in optionsValuesIds) 
    {
       //if you are using the 'third class'
       Config_OptionVal cnfOpt = new Config_OptionVal();
       cnfOpt.ConfigurationCollection = con;
       cnfOpt.OptionValueID = optionValueId;
       db.Config_OptionVal.Add(cnfOpt);

       //if you are NOT using the 'third class' 
       OptionValue optVal = db.OptionValues.Find(optionsValuesIds);
       con.OptionValues.Add(optVal);
    }
    db.SaveChanges();
}

View:

<input type="checkbox" name="OptionValuesIds" value="@ov.OptionValueID"  id="OptionValues"/>@ov.OptionVal

Models:

If you are using the 'third class', modify your classes as follows:

public class ConfigurationCollection
{
    //...
    //public virtual ICollection<OptionValue> OptionValues { get; set; }
    public virtual ICollection<Config_OptionVal> OptionValues { get; set; }
}

public class OptionValue
{
   //...
   //public virtual ICollection<ConfigurationCollection> ConfigurationCollections { get; set; }
   public virtual ICollection<Config_OptionVal> ConfigurationCollections { get; set; }

}

If you are not using the 'third class':

public class ConfigurationCollection
{
    //...
    public virtual ICollection<OptionValue> OptionValues { get; set; }
}
public class OptionValue
{
    //...
    public virtual ICollection<ConfigurationCollection> ConfigurationCollections { get; set; }

}

Upvotes: 1

Related Questions