Updating many-to-many relationship using Entity Framework Core

187 views Asked by At

I have three tables to denote many to many relationships. The models are shown here:

public class Feature
{
    public Guid Id { get; set; }
    public string Name { get; set; }       
    //Navigation Properties  
    public List<Menu> Menus { get; } = new();
    public List<FeatureMenu> FeatureMenus { get; } = new();
}

public class Menu
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    //Navigation Properties
    public List<Feature> Features { get; } = new();        
    public List<FeatureMenu> FeatureMenus { get; } = new();
}

[Table("FeatureMenus")]
public class FeatureMenu
{        
    public Guid FeatureId { get; set; }     
    public Guid MenuId { get; set; }
    //Navigation Properties
    public Feature Feature { get; set; } = null!;
    public Menu Menu { get; set; } = null!;    
}

I am using this Add method to add a menu and any Features the menu may belong to:

public async Task<Menu> CreateAsync(List<Guid> featuresId, Menu menu)
{
    foreach(var featureId in featuresId)
    {
        var feature = await db.Features.FirstOrDefaultAsync(x => x.Id == featureId);

        if (feature != null)
        {
            menu.Features.Add(feature);
        }
    }

    await db.Menus.AddAsync(menu);
    await db.SaveChangesAsync();

    return menu;
}

This code works and the data is inserted into Menu as well as the join table FeatureMenu.

Question #1: is this the most efficient way of adding into parent and child/join table?

Question #2: is related to updating Menu and FeatureMenu entities. I am using below code to update the Menu table, however, I am stuck on how to add or remove entries from FeatureMenu table based on the List<Guid> FeaturesId parameter passed to the UpdateAsync method. A client application may add or remove entries from FeaturesId when conducting an update.

public async Task<Menu?> UpdateAsync(Guid id, List<Guid> FeaturesId, Menu menu)
{
    var existingMenu = await db.Menus.FirstOrDefaultAsync(x => x.Id == id);

    if (existingMenu == null)
    {
        return null;
    }

    menu.Id = id;
    mapper.Map(menu, existingMenu);
    
    await db.SaveChangesAsync();

    return existingMenu;
}
0

There are 0 answers