Home > other >  How to store multi values Ex (skills) in Asp.net core mvc
How to store multi values Ex (skills) in Asp.net core mvc

Time:06-06

I want to store multiple values from a dropdown using .NET Core MVC and Entity Framework. I have no idea how to do that. This is my model code.

public class Project
{
    [Key]
    public int Id { get; set; }
    [Required]
    public string Title { get; set; }

    public string? Description { get; set; }
    public List<int> SkillsID { get; set; }
    [ValidateNever]
    public List<Skill> skills { get; set; }


}

CodePudding user response:

Start here (https://docs.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api,fluent-api-simple-key,simple-key ) to understand relationships in EF. In your case you will likely want to set up a Many-to-Many relationship between Projects and Skills. This assumes you will have a list of Skills where by each Project associates itself with 0, 1, or many of those skills. In this case you would have classes like:

public class Project 
{
    // ... project properties.

    public virtual ICollection<Skill> Skills { get; protected set; } = new List<Skill>();
}

public class Skill
{
    //  ... skill properties.
}

When mapped, you tell EF that Project .HasMany(x => x.Skills).WithMany() as we likely don't need a Projects collection on each individual Skill entity. The last step is telling EF how to associate these two entities. In Many-to-Many relationships this involves a joining table such as a ProjectSkills table:

[tbl:ProjectSkills]
    - PK,FK - ProjectId
    - PK,FK - SkillId

You don't track lists of FKs in the entity. Think of it from a database perspective. When relating tables together with FKs, you don't have an array or such of FKs within a single row. You use a joining table.

The PK for the table is a composite between the Project ID and Skill ID, where each of those is a FK back to the corresponding table. EF can create this table by convention or you can configure it manually if you want to fine-tune the naming.

If you want to track more detail about the relationship such as tracking a CreatedDate etc. then you will need to map the relationship as an entity which would look like:

public class Project 
{
    // ... project properties.

    public virtual ICollection<ProjectSkill> ProjectSkills { get; protected set; } = new List<ProjectSkill>();
}

public class Skill
{
    //  ... skill properties.
}

public class ProjectSkill
{
    [Key, Column(Order = 0)]
    public int ProjectId { get; set; }
    [Key, Column(Order = 1)]
    public int SkillId { get; set; }

    public DateTime CreatedDateTime { get; set; }
    // .. Other details about the relationship.

    [ForeignKey("ProjectId")]
    public virtual Project Project { get; set; }
    [ForeignKey("SkillId")]
    public virtual Skill Skill { get; set; }
}

You may come across examples for EF core using these joining entities as this was required in earlier versions of EF Core (2, 3.1) for all Many-to-Many relationships.

For a One-to-Many where skills specifically belong to a Project, then a ProjectID would be put into the Skill table. The Project entity would have the same collection of Skills, but the mapping would be a: .HasMany(x => x.Skills).WithOne() Where the Skill table would contain a ProjectID to associate itself to a given project. EF can represent this relationship as a one-way where Project has the collection and Skill doesn't expose a reference to Project, or bi-directional where you can add a Project reference into Skill. (.HasMany(x => x.Skills).WithOne(x => x.Project))

  • Related