简体   繁体   中英

Entity Framework does not add value to one column

I want to export data from JSON file to SQL database using Entity Framework. I am doing it like this:

// If database is empty, seed data        
if (!_context.Classes.Any())
{
    var classes = JsonConvert.DeserializeObject<List<Class>>(await File.ReadAllTextAsync("PATH\\data.json"));

    foreach (var @class in classes)
    {
        await _classRepository.AddClass(@class);
        await _classRepository.SaveChanges();
    }

    var updatedPupils = new List<Pupil>();

    foreach (var @class in classes)
    {
        foreach (var pupil in @class.Pupils)
        {
            var copy = pupil;
            copy.GradutaionYear = @class.GraduationYear;
            updatedPupils.Add(copy);
        }
   }

   foreach (var pupil in updatedPupils)
   {
       await _pupilRepository.AddPupil(pupil);
       await _pupilRepository.SaveChanges();
   }
}

In this method I am updating pupil field called GraduationYear by copying the value from class entity from filed called GraduationYear . But after this operation, the GraduationYear field has not been updated in the database, it remains null.

Screenshot

How can I fix it?

edit

After check in debugger, one thing I am sure, entities in updatedPupils list have correct value in GraduationYear field.

Classes code

public class Class
{
    public Guid Id { get; set; }
    public ICollection<Pupil> Pupils { get; set; }
    public string SchoolName { get; set; }
    public string ClassName { get; set; }
    public string ClassProfile { get; set; }
    public string GraduationYear { get; set; }
    public string ClassPhoto { get; set; }
    public string Description { get; set; }
}

public class Pupil
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public string Photo { get; set; }
    public string GradutaionYear { get; set; }
    public string Description { get; set; }
    public Class Class { get; set; }
}

edit 2

public async Task<Pupil> AddPupil(Pupil entity)
{
    var result = await _context.Pupils.AddAsync(entity);
    return result.Entity;
}

First, take a look to this code :

var copy = pupil;
copy.GradutaionYear = @class.GraduationYear;
updatedPupils.Add(copy);

In c#, the symbol equal = copy a variable but keep a reference to origin variable, so when you do copy.GradutaionYear = @class.GraduationYear you update both GradutaionYear properties of copy and pupil vars.

So, this code var copy = pupil; copy.GradutaionYear = @class.GraduationYear; var copy = pupil; copy.GradutaionYear = @class.GraduationYear; is the same as doing pupil.GradutaionYear = @class.GraduationYear .

Second, do a SaveChange() in a loop, it's a very very very bad idea and can be very heavy, very long, and can throw stack OverFlow exception. You could use that in specific case if you don't have any others choices, but you must be sure of what you are doing.

Thridly, SaveChange() will save entities and children entities too. So adding classes will also add children pupils to database.

By knowing all of that, you can simplify your code to :

foreach (var @class in classes)
{
    foreach (var pupil in @class.Pupils)
        pupil.GradutaionYear = @class.GraduationYear;
    await _classRepository.AddClass(@class);
}
await _classRepository.SaveChanges();

This should work, tell me if you have any trouble

I found my mistake. When I was only adding classes , it also added pupils to database. Solution is simple. Update pupils before adding them to database.

foreach (var @class in classes)
{
    foreach (var pupil in @class.Pupils)
    {
        pupil.GradutaionYear = @class.GraduationYear;
    }

    await _classRepository.AddClass(@class);
}

await _classRepository.SaveChanges();

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