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.
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.