Home > Blockchain >  Entity Framework Core problem with add record to table with relationship
Entity Framework Core problem with add record to table with relationship

Time:02-21

I have defined two tables, one called project and the other is called task, and they have a one-to-many relationship. But when I want to insert a new blank project without any tasks, it wont let me to so, and it requires a task to be filled in.

Here are my model classes:

public class Project
{
    [Key]
    public int ProjectId { get; set; }
    public string ProjectName { get; set; }
    public string ProjectDescription { get; set; }
    public string ProjectOwnerId { get; set; }
    public DateTime ProjectDate { get; set; }

    public virtual ICollection<Tasks> Tasks { get; set; }
}

public class Tasks
{
    [Key]
    public int TaskId { get; set; }
    [Required]
    public string TaskName { get; set; }
    public string TaskDescription { get; set; }
    public string TaskTag { get; set; }
    public DateTime TaskStartTime { get; set; }
    public DateTime TaskEndTime { get; set; }

    public int ProjectId { get; set; }
    public virtual Project Project { get; set; }
}

And I register them in the DbContext like this

public class DataContext : DbContext
{
    public DataContext(DbContextOptions<DataContext> options) : base(options) { }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Tasks>()
            .HasOne<Project>(t => t.Project)
            .WithMany(p => p.Tasks)
            .HasForeignKey(s => s.ProjectId);
    }

    public DbSet<Project> project { get; set; }
    public DbSet<Tasks> task { get; set; }
}

And in the repository I want to add a new model like this

 public async Task<Project> Create(Project project)
 {
        try
        {
            if (project != null)
            {
                project.Tasks = null;
                var obj = _DataContext.Add<Project>(project);
                await _DataContext.SaveChangesAsync();
                return obj.Entity;
            } 
            else
            {
                throw new ArgumentNullException("The input is not a valid project");
            }
        } 
        catch (Exception)
        {
            throw;
        }
}

And my controller handles the request like this

public ActionResult<Project> AddProject([FromBody] Project project)
{
    return Ok(serviceProject.Create(project));
}

When I try this in my swagger api tester I get the following error

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "00-21132b17245e9e597ad82447917c067a-401b35711e6e9645-00",
  "errors": {
    "Tasks": [
      "The Tasks field is required."
    ]
  }
}

Is there anyone who knows what the problem could be?

Thanks a lot!

CodePudding user response:

All new projects in VS 2022 have <nullable>enable</nullable> set in the .csproj files.

This turns on Nullable reference types by default. This in turn means that every reference type property must have a non-null-value after deserialization.

That is the exact error you are getting from your deserializer (probably System.Text.Json). It expects a value for public virtual ICollection<Tasks> Tasks { get; set; } because it is not marked as nullable.

The error has nothing to do with your database setup, it is just the nullablility and the JSON serializer.

To fix it, you can either declare it as nullable

public virtual ICollection<Tasks>? Tasks { get; set; }

or maybe even better, assign it a default value, so you can be sure it is not null.

public virtual ICollection<Tasks> Tasks { get; set; } = new HashSet<Tasks>();

CodePudding user response:

I think the problem is with your model builder. change it to the following and see if it works:

modelBuilder.Entity<Project>().HasMany(t => t.Tasks).WithOne().HasForeignKey(c => c.ProjectId)
  • Related