EF one-to-many to assure the link with the main table.

sblb 1,166 Reputation points
2022-11-12T15:27:52.21+00:00

Hi,
I would like to do a link between main table Developer & a table ActionList.

The ActionList take place in edit mode of my app to the address : "/developer/edit/{developerId:int}"

I try to use EF one-to-many to do the link between two tables

I structured the model class has below :

public partial class Developer  
     {  
         public int Id { get; set; }  
          public ICollection<ActionsList>? ActionsLists { get; set; }  
  }  
      
  public class ActionsList  
     {  
         [Key]     
         public int ActionId { get; set; }              
           
         public DateTime ProductionDate { get; set; }  
              
         public int DeveloperId { get; set; }  
         public Developer Developer { get; set; }  
      
     }  

application data :

 public class ApplicationDBContext : DbContext  
     {  
         public ApplicationDBContext(DbContextOptions<ApplicationDBContext> options) : base(options)  
         {  
         }  
         public DbSet<Developer> Developers { get; set; }  
         public DbSet<ActionsList> ActionsLists { get; set; }  
                     
          
         protected override void OnModelCreating(ModelBuilder modelBuilder)  
         {  
             modelBuilder.Entity<ActionsList>()  
                         .HasOne<Developer>(s => s.Developer)  
                         .WithMany(g => g.ActionsLists)  
                         .HasForeignKey(s => s.DeveloperId);         
         }     
          
       }  

when I want to add the actions in page https://localhost:44354/developer/edit/1 this means all actions for developerId = 1 ; any value has posted in ActionList.

But when I've put the break point await http.PostAsJsonAsync("api/actionslist", act); I see that ActionId = null .

I guess that I set up EF one-to-many wrong!

Can you help me how to link the two tables? (This is the first time I've done this)

Thanks in advance

Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,386 questions
{count} votes

Accepted answer
  1. AgaveJoe 26,201 Reputation points
    2022-11-18T12:45:54.757+00:00

    Against my better judgement, I created an example. This is an example NOT a solution. In production code you would NOT pass entities between the client and Web API! Typically you would designed a data interrace and pass poco classes.

    I used followed the following documentation which I have provided many times over many of your threads.

    Tutorial: Create a web API with ASP.NET Core
    Saving Related Data

    Entities

        public partial class Developer  
        {  
            public int DeveloperId { get; set; }  
            public List<ActionItem>? ActionItems { get; set; }  
        }  
      
        public class ActionItem  
        {  
            public int ActionItemId { get; set; }  
            public string? Tilte { get; set; }  
            public string? Description { get; set; }  
            public string? State { get; set; }  
            public DateTime? OpenDate { get; set; }  
            public DateTime? PlanDate { get; set; }  
            public DateTime? CloseDate { get; set; }  
      
            public int DeveloperId { get; set; }  
            public Developer? Developer { get; set; }  
          
    

    Related data configuration

            protected override void OnModelCreating(ModelBuilder modelBuilder)  
            {  
                modelBuilder.Entity<ActionItem>()  
                    .HasOne(d => d.Developer)  
                    .WithMany(d => d.ActionItems);  
            }  
    

    Controller

        [Route("api/[controller]")]  
        [ApiController]  
        public class DeveloperActionController : ControllerBase  
        {  
            private readonly WebApiSqliteContext _context;  
            public DeveloperActionController(WebApiSqliteContext context)  
            {  
                _context = context;  
            }  
            // GET: api/<DeveloperActionController>  
            [HttpGet]  
            public IEnumerable<Developer> GetDevelopersWithActions()  
            {  
                return _context.Developers.Include(a => a.ActionItems).ToList();  
            }  
      
            // GET api/<DeveloperActionController>/5  
            [HttpGet("{id}")]  
            public async Task<ActionResult<Developer>> GetDeveloperActions(int id)  
            {  
                Developer? developer = await _context.Developers  
                    .Include(a => a.ActionItems)  
                    .FirstOrDefaultAsync(d => d.DeveloperId == id);  
      
                if (developer == null)  
                {  
                    return NotFound();  
                }  
      
                return Ok(developer);  
            }  
      
            // POST api/<DeveloperActionController>  
            [HttpPost]  
            public async Task<ActionResult<Developer>> PostAsync([FromBody] Developer developer)  
            {  
                _context.Developers.Add(developer);  
                await _context.SaveChangesAsync();  
      
                return CreatedAtAction(nameof(GetDeveloperActions), new { id = developer.DeveloperId }, developer);  
            }  
      
            // PUT api/<DeveloperActionController>/5  
            [HttpPut("{id}")]  
            public async Task<ActionResult<Developer>> Put(int id, [FromBody] ActionItem actionItem)  
            {  
                Developer? developer = await _context.Developers  
                    .Include(a => a.ActionItems)  
                    .FirstOrDefaultAsync(d => d.DeveloperId == id);  
      
                if (developer == null)  
                {  
                    return NotFound();  
                }  
      
                developer.ActionItems.Add(actionItem);  
                await _context.SaveChangesAsync();  
      
                return CreatedAtAction(nameof(GetDeveloperActions), new { id = developer.DeveloperId }, developer);  
      
            }  
      
            // DELETE api/<DeveloperActionController>/5  
            [HttpDelete("{id}")]  
            public async Task<IActionResult> Delete(int id)  
            {  
                Developer? developer = await _context.Developers  
                    .Include(a => a.ActionItems)  
                    .FirstOrDefaultAsync(d => d.DeveloperId == id);  
      
                if (developer == null)  
                {  
                    return NotFound();  
                }  
      
                _context.Remove(developer);  
      
                await _context.SaveChangesAsync();  
      
                return NoContent();  
            }  
        }  
    

    Post data

    {  
      "developerId": 0,  
      "actionItems": [  
        {  
          "actionItemId": 0,  
          "tilte": "Action Title",  
          "description": "Description",  
          "state": "State",  
          "openDate": "2022-11-17",  
          "planDate": "2022-11-17",  
          "closeDate": "2022-11-17",  
          "developerId": 0  
        }  
      ]  
    }  
      
    

    Put data

    {  
      "actionItemId": 0,  
      "tilte": "Action Title 2",  
      "description": "Description 2",  
      "state": "State 2",  
      "openDate": "2022-11-18",  
      "planDate": "2022-11-18",  
      "closeDate": "2022-11-18",  
      "developerId": 1  
    }  
    

    Configuration is needed to return a entity otherwise you'll get an error.

    builder.Services.AddControllers().AddJsonOptions(x =>  
                    x.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles);  
    
    0 comments No comments

13 additional answers

Sort by: Most helpful
  1. AgaveJoe 26,201 Reputation points
    2022-11-22T13:50:50.193+00:00

    The Developer class you've shared is a partial class. I'm wondering if there is another partial class that defines a primary key named Id which makes this whole thread is a waste of everyone's time.