简体   繁体   中英

Entity Framework only saving some of my fields

I'm trying to write a small web api and it is my first time using entity framework.

My problem is that only some of my data gets saved.

I have this GET method which is just supposed to save a model into the database:

[HttpGet]
public async Task<IActionResult> PopulateDB()
{
    var playerOneQuest = new StatusModel
    {
        PlayerId = "1",
        points= 250,
        completedSteps = new List<Status>()
        {
            new Status
            {
                Id = 11,
                Index = 1
            } 
        }
    };
    
    _context.Quest.Add(playerOneQuest);
    await _context.SaveChangesAsync();

    return Ok("Added data"); // Breakpoint here
}

When I add a breakpoint at the last line _context looks perfectly fine with all the data, but as soon as the method has executed completedSteps will be null. The other data - PlayerId & points - are saved just fine.

I have tried adding this _context.Entry(playerOneQuest).State = EntityState.Added; before calling SaveChangesAsync() , but completedSteps still ends up null after the method has executed.

_context is defined as:

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

    public virtual DbSet<StatusModel> Quest { get; set; } = null!;
}

The 2 models used are defined as:

public class StatusModel
{
    [Key]
    public string? PlayerId {get;set;}
    public long Points{get;set;}
    public List<Status> completedSteps {get;set;} = null!;
}

public class Status
{
    public long Id {get;set;}
    public int Index {get;set;}
}

And for good measure, this is how the database context is added to my web app:

builder.Services.AddDbContext<QuestContext>(opt =>
opt.UseInMemoryDatabase("Quests"));

In models:

 public class StatusModel
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public long Id {get;set;}
        public long Points{get;set;}
        public List<Status> completedSteps {get;set;} = new List<Status>();
    }
    
    public class Status
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public long Id {get;set;}
        public int Index {get;set;}
        public long StatusModelId {get;set;}
        public StatusModel {get;set;}
    }

In your storage context in OnModelCreating :

modelBuilder.Entity<Status>().HasOne(c => c.StatusModel).WithMany(c => c.completedSteps)
                    .HasForeignKey(c => c.StatusModelId).OnDelete(DeleteBehavior.Cascade);

You have to set up the relations between objects. You can do it in your Context with fluent API, or with attributes directly in the models. Also in your context you need both DbSets, for status and for statusModel.

Wrote the answer without testing, should be close enough though. Here is a link to relations: Relations in EF

I missed your PlayerId - this is I guess an FK to Player? Than you have to set up that relation as well. If you intended it as PK, it probably should not be nullable.

I think you should use [HttpPost], not [HttpGet]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM