I am trying to update a table and its related entities but the child entities are not updating. I don't know if the child entities should update automatically, or if I need to manually update them. Or I don't know if my EF configuration or database configuration are incorrect.
My tables are Template and TemplateFields. A template can have many templateFields but a templateField can only have one parent template. Here is my diagram.
And here are my table configurations in EF:
public class TemplateConfiguration : EntityConfiguration<Template>
{
public override void Configure(EntityTypeBuilder<Template> builder)
{
base.Configure(builder);
builder.HasMany(template => template.TemplateFields)
.WithOne(field => field.ParentTemplate)
.OnDelete(DeleteBehavior.Cascade);
}
}
public class TemplateFieldConfiguration : EntityConfiguration<TemplateField>
{
public override void Configure(EntityTypeBuilder<TemplateField> builder)
{
base.Configure(builder);
builder.HasOne(field => field.ParentTemplate)
.WithMany(template => template.TemplateFields);
}
}
Here's the Template model:
[Table("Template")]
public class Template : Entity
{
[Required]
public virtual string Name { get; set; }
public virtual IList<TemplateField> TemplateFields { get; set; }
}
Here's the TemplateField model:
[Table("TemplateField")]
public class TemplateField : Entity
{
[Required]
public virtual Template ParentTemplate { get; set; }
[Required]
public virtual string Name { get; set; }
[Required]
public virtual DataType DataType { get; set; }
[Required]
public virtual bool IsSharedAcrossLanguages { get; set; }
}
Here is the Template update method:
public virtual async Task<Template> EditAsync(Template template)
{
var originalItem = await _dbContext.Template.FindAsync(template.Id);
_dbContext.Entry(originalItem).CurrentValues.SetValues(template);
await _dbContext.SaveChangesAsync();
var newTemplate = await _dbContext.Template.FindAsync(template.Id);
return newTemplate;
}
Here is some example JSON payload I've been testing with to add a template and associated fields:
{
"name": "New Template",
"fields": [
{
"name": "Title",
"dataType": "text",
"isSharedAcrossLanguages": false
},
{
"name": "Content",
"dataType": "image",
"isSharedAcrossLanguages": true
},
{
"name": "Header",
"dataType": "text",
"isSharedAcrossLanguages": false
}
]
}
And last of all here is the payload for updating a template and its fields (with example Guids):
{
"id": "32e2ff27-24e6-49d4-bea7-08d924513aa3",
"name": "Edited Template",
"fields": [
{
"id": "80072a3a-c717-4ab0-53ef-08d924513aae",
"name": "Edited Title",
"dataType": "text",
"isSharedAcrossLanguages": false
},
{
"id": "3865f8b1-0f3c-4edc-53f0-08d924513aae",
"name": "Content",
"dataType": "image",
"isSharedAcrossLanguages": true
},
{
"id": "57b5b7af-d265-4244-53f1-08d924513aae",
"name": "Header",
"dataType": "text",
"isSharedAcrossLanguages": false
}
]
}
What's confusing to me is the standard EF method AddAsync()
will cascade adding child templateFields automatically, which tells me cascading updates should be possible. What I'm thinking is that '_dbContext.Entry(originalItem).CurrentValues.SetValues(template);' only gets values that have changed and since my Template table does not contain a foreign key column pointing to the TemplateField table, EF can't recognize it as a changed value.
Is that a correct assumption? If so, is there a way to get cascading updates to work?