Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Foreign key merge statement error in asp.net when submitting form

I have 2 models, one for Poll and for PollOption. In the create action, I want to add 1 Poll to the database and a list of PollOptions as well. Each PollOption has a foreign key PollId.

When I submit the form, an error occurs because the foreign key is null or 0. I assume this is because the Id of the poll is not ready before the Save function is called thus it is 0 but how can I fix that? The error I get is:

The MERGE statement conflicted with the FOREIGN KEY constraint "FK_PollOptions_Polls_PollId". The conflict occurred in database "favpolls", table "dbo.Polls", column ‘Id’

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Models:

public class Poll
{
    [Key]
    public int Id { get; set; }

    [Required]
    public string Question { get; set; } = "";
}

public class PollOption
{
    [Key]
    public int Id { get; set; }

    [Required]
    public string Option { get; set; } = "";

    [Required]
    public int PollId { get; set; }

    [ForeignKey("PollId")]
    [ValidateNever]
    public Poll Poll { get; set; }
}

View model:

public class PollVM
{
    public Poll Poll { get; set; }

    [ValidateNever]
    public List<PollOption> PollOptions { get; set; }
}

Action:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(PollVM pollVM) 
{
    _unitOfWork.Poll.Add(pollVM.Poll);

    foreach (var option in pollVM.PollOptions)
    {
        _unitOfWork.PollOption.Add(option);
    }

    _unitOfWork.Save();

    return View(pollVM);
}

View:

@model PollVM
<div class="index-container">
    <div class="subcontainer">
        <h1 class="title">Poll Creator</h1>
        <h2 class="subtitle">Complete the form below to create your poll!</h2>
        <form method="POST" asp-action="Create">
            <input asp-for="Poll.Id" type="hidden" />
            <div class="form-container">
                <div class="form-input">
                    <label asp-for="Poll.Question">Question:</label>
                    <input asp-for="Poll.Question" type="text" placeholder="Type the poll question here" required>
                </div>
                <div class="form-input">
                    <div class="form-input form-options">
                        <label>Answer Options:</label>
                        <div class="form-option">
                            <input asp-for="PollOptions[0].Id" type="hidden" />
                            <input asp-for="PollOptions[0].PollId" type="hidden" />
                            <input asp-for="PollOptions[0].Option" type="text" placeholder="Option 1" required>
                            <img src="~/images/icons/cross.svg" alt="remove-option" width="30px" class="remove-option" onclick="removeOption(this)">
                        </div>
                        <div class="form-option">
                            <input asp-for="PollOptions[1].Id" type="hidden" />
                            <input asp-for="PollOptions[1].PollId" type="hidden" />
                            <input asp-for="PollOptions[1].Option" type="text" placeholder="Option 2" required>
                            <img src="~/images/icons/cross.svg" alt="remove-option" width="30px" class="remove-option" onclick="removeOption(this)">
                        </div>
                    </div>
                    <button type="button" class="button side-button icon-button">Add Option <img src="~/images/icons/plus.svg" alt="add-option" width="25px"></button>
                </div>
                <button type="submit" class="button submit-button">Create!</button>
            </div>
        </form>
    </div>
</div>

@section Scripts {
    <script src="~/js/answer-options.js" asp-append-version="true"></script>
}

If I remove the poll option "add" functions, the action works correctly and only adds 1 poll which is what I want but I want it to add the poll options as well.

>Solution :

If _unitOfWork.PollOption provides a DbSet that does not need to be changed, but if you use methods that you yourself such as Repositories, you should add the method with the following signature to UnitOfWork

_unitOfWork.PollOption.AddRange(IEnumrable<PollOption> polOptions);

and try this code :

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(PollVM pollVM) 
{
    pollVM.PollOptions.ForEach(p => p.Poll = pollVM.Poll);
    
    _unitOfWork.PollOption.AddRange(pollVM.PollOptions);
     
    _unitOfWork.Save();

    return View(pollVM);
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading