'HTTP Post creates related data instead of referencing it using EF Core
I'm a bit new to the community so please forgive any unusual formatting issues and if there is any other data or background information I can provide please don't hesitate to ask.
I've got four tables that all have one form of relationship or another. I am trying to test my controller for the ECO_Req which was auto-generated with scaffolding (as were the entities; database first approach) and when I use swagger to create a POST request I get unexpected behavior. The POST request is writing new data to all the foreign key tables instead of referencing or looking up the data from the provided IDs. Below are all the EF classes along with an example of my swagger test.
The swagger JSON Post Request below is what I have tried to use and I have been getting a violation of unique key constraint. How can I get this POST request to stop creating new data for the foreign keys and use existing data instead?
{
"ecrId": 1,
"reqId": 1,
"completed": true,
"contactId": 1,
"ecoSent": true,
"ecnSent": true,
"contact": {
"name": "string",
"upn": "string",
"supervisor": true,
"approver": true,
"endUser": true,
"ecoReqs": []
},
"ecr": {
"submittedBy": "string",
"submissionTimestamp": "2022-04-21T12:40:29.177Z",
"description": "string",
"reason": "string",
"proposedChange": "string",
"originId": 0,
"changeTypeId": 0,
"championId": 0,
"stakeholderId": 0,
"statusId": 0,
"ecrPartNumbers": 0,
"ecrDrawings": 0,
"ecrModelAffected": 0,
"respForExecution": "string",
"proposedSolution": "string",
"statusDate": "2022-04-21T12:40:29.177Z",
"notes": "string",
"attachments": "string",
"isActive": true,
"ecrNo": "string",
"ecoNo": "string",
"ecns": [],
"ecoReqs": [],
"ecrChampions": [],
"ecrDrawingsNavigation": [],
"ecrModelsAffecteds": [],
"ecrNotes": [],
"ecrResponsibleForExecutions": [],
"ecrStakeholders": []
},
"req": {
"description": "string",
"parentId": 0,
"ecoReqs": [],
"children": [],
"isSelected": true
}
}
Controller below is boilerplate code generated by scaffolding. POST request is what I am having issues with.
// GET: api/EcoReqs
[HttpGet]
public async Task<ActionResult<IEnumerable<EcoReq>>> GetEcoReqs()
{
return await _context.EcoReqs.ToListAsync();
}
// GET: api/EcoReqs/5
[HttpGet("{id}")]
public async Task<ActionResult<EcoReq>> GetEcoReq(int id)
{
var ecoReq = await _context.EcoReqs.FindAsync(id);
if (ecoReq == null)
{
return NotFound();
}
return ecoReq;
}
// PUT: api/EcoReqs/5
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
[HttpPut("{id}")]
public async Task<IActionResult> PutEcoReq(int id, EcoReq ecoReq)
{
if (id != ecoReq.Id)
{
return BadRequest();
}
_context.Entry(ecoReq).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!EcoReqExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
// POST: api/EcoReqs
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
[HttpPost]
public async Task<ActionResult<EcoReq>> PostEcoReq(EcoReq ecoReq)
{
_context.EcoReqs.Add(ecoReq);
await _context.SaveChangesAsync();
return CreatedAtAction("GetEcoReq", new { id = ecoReq.Id }, ecoReq);
}
[Table("ECO_Req_Master", Schema = "dbo")]
public partial class EcoReqMaster
{
public EcoReqMaster()
{
EcoReqs = new HashSet<EcoReq>();
}
[Key]
[Column("ID")]
public int Id { get; set; }
[StringLength(50)]
[Unicode(false)]
public string Description { get; set; } = null!;
[Column("Parent_ID")]
public int ParentId { get; set; }
[InverseProperty("Req")]
public virtual ICollection<EcoReq> EcoReqs { get; set; }
//children added in order to be able to get a nested list for use in front end material checkbox tree/hierarchy
[NotMapped]
public IList<EcoReqMaster>? Children { get; set; } = new List<EcoReqMaster>();
//selected property added in order to track which checkboxes have been selected in front end
[NotMapped]
public bool isSelected { get; set; }
}
[Table("ECO_Req", Schema = "dbo")]
public partial class EcoReq
{
[Key]
[Column("ID")]
public int Id { get; set; }
[Column("ECR_ID")]
public int EcrId { get; set; }
[Column("REQ_ID")]
public int ReqId { get; set; }
public bool Completed { get; set; }
[Column("Contact_ID")]
public int ContactId { get; set; }
[Column("ECO_Sent")]
public bool? EcoSent { get; set; }
[Column("ECN_Sent")]
public bool? EcnSent { get; set; }
[ForeignKey("ContactId")]
[InverseProperty("EcoReqs")]
public virtual EcmDirectory Contact { get; set; } = null!;
[ForeignKey("EcrId")]
[InverseProperty("EcoReqs")]
public virtual Ecr Ecr { get; set; } = null!;
[ForeignKey("ReqId")]
[InverseProperty("EcoReqs")]
public virtual EcoReqMaster Req { get; set; } = null!;
}
[Table("ECM_Directory", Schema = "dbo")]
public partial class EcmDirectory
{
public EcmDirectory()
{
EcoReqs = new HashSet<EcoReq>();
}
[Key]
[Column("ID")]
public int Id { get; set; }
[StringLength(255)]
[Unicode(false)]
public string Name { get; set; } = null!;
[Column("UPN")]
[StringLength(255)]
[Unicode(false)]
public string Upn { get; set; } = null!;
public bool Supervisor { get; set; }
public bool Approver { get; set; }
[Column("End_User")]
public bool EndUser { get; set; }
[InverseProperty("Contact")]
public virtual ICollection<EcoReq> EcoReqs { get; set; }
}
[Table("ECR", Schema = "dbo")]
[Index("EcrNo", Name = "Unique_ECR_No", IsUnique = true)]
public partial class Ecr
{
public Ecr()
{
Ecns = new HashSet<Ecn>();
EcoReqs = new HashSet<EcoReq>();
EcrChampions = new HashSet<EcrChampion>();
EcrDrawingsNavigation = new HashSet<EcrDrawing>();
EcrModelsAffecteds = new HashSet<EcrModelsAffected>();
EcrNotes = new HashSet<EcrNote>();
EcrResponsibleForExecutions = new HashSet<EcrResponsibleForExecution>();
EcrStakeholders = new HashSet<EcrStakeholder>();
}
[Key]
[Column("ID")]
public int Id { get; set; }
[Column("Submitted_By")]
[StringLength(255)]
[Unicode(false)]
public string SubmittedBy { get; set; } = null!;
[Column("Submission_Timestamp", TypeName = "datetime")]
public DateTime? SubmissionTimestamp { get; set; }
[Unicode(false)]
public string? Description { get; set; }
[StringLength(255)]
[Unicode(false)]
public string? Reason { get; set; }
[Column("Proposed_Change")]
[StringLength(255)]
[Unicode(false)]
public string? ProposedChange { get; set; }
[Column("Origin_ID")]
public int? OriginId { get; set; }
[Column("Change_Type_ID")]
public int? ChangeTypeId { get; set; }
[Column("Champion_ID")]
public int? ChampionId { get; set; }
[Column("Stakeholder_ID")]
public int? StakeholderId { get; set; }
[Column("Status_ID")]
public int? StatusId { get; set; }
[Column("ECR_Part_Numbers")]
public int? EcrPartNumbers { get; set; }
[Column("ECR_Drawings")]
public int? EcrDrawings { get; set; }
[Column("ECR_Model_Affected")]
public int? EcrModelAffected { get; set; }
[Column("Resp_for_Execution")]
[StringLength(50)]
[Unicode(false)]
public string? RespForExecution { get; set; }
[Column("Proposed_Solution")]
[StringLength(50)]
[Unicode(false)]
public string? ProposedSolution { get; set; }
[Column("Status_Date", TypeName = "date")]
public DateTime? StatusDate { get; set; }
[StringLength(50)]
[Unicode(false)]
public string? Notes { get; set; }
[StringLength(10)]
public string? Attachments { get; set; }
[Column("isActive")]
public bool IsActive { get; set; }
[Column("ECR_No")]
[StringLength(20)]
[Unicode(false)]
public string EcrNo { get; set; } = null!;
[Column("ECO_No")]
[StringLength(20)]
[Unicode(false)]
public string? EcoNo { get; set; }
[InverseProperty("Ecr")]
public virtual ICollection<Ecn> Ecns { get; set; }
[InverseProperty("Ecr")]
public virtual ICollection<EcoReq> EcoReqs { get; set; }
[InverseProperty("Ecr")]
public virtual ICollection<EcrChampion> EcrChampions { get; set; }
[InverseProperty("Ecr")]
public virtual ICollection<EcrDrawing> EcrDrawingsNavigation { get; set; }
[InverseProperty("Ecr")]
public virtual ICollection<EcrModelsAffected> EcrModelsAffecteds { get; set; }
[InverseProperty("Ecr")]
public virtual ICollection<EcrNote> EcrNotes { get; set; }
[InverseProperty("Ecr")]
public virtual ICollection<EcrResponsibleForExecution> EcrResponsibleForExecutions { get; set; }
[InverseProperty("Ecr")]
public virtual ICollection<EcrStakeholder> EcrStakeholders { get; set; }
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
