2

I have the following action method to add a parent (Submission) and child (SubmissionQuestionSubmission) objects:

public async Task<IActionResult> Create([Bind("Submission,SubmissionQuestionSubmission")] SubmissionCreate sc )
{
    if (ModelState.IsValid)
    {
        var newsubmission  =  _context.Submission.Add(sc.Submission);
        sc.Submission.Created = DateTime.Now;
        await _context.SaveChangesAsync();

        foreach (var v in sc.SubmissionQuestionSubmission)
        {
            v.SubmissionId = sc.Submission.Id;//i though this will be null..
            _context.SubmissionQuestionSubmission.Add(v);
        }

        await _context.SaveChangesAsync();
    }
}

At first I thought that the code will not work as the sc.Submission.Id parent foreign key will be null, since I have just added the submission object. but my code work well, so how did the ASP.NET Core MVC and Entity Framework Core retrieved the Id of the newly added object? Will it automatically do a round trip to the database?

Here are my model classes:

public partial class Submission
{
    public Submission()
    {
        SubmissionQuestionSubmission = new HashSet<SubmissionQuestionSubmission>();
    }

    public long Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime? Created { get; set; }

    public virtual ICollection<SubmissionQuestionSubmission> SubmissionQuestionSubmission { get; set; }
}

public partial class SubmissionQuestionSubmission
{
        public int SubmissionQuestionId { get; set; }
        public long SubmissionId { get; set; }
        public bool? Answer { get; set; }

        public virtual Submission Submission { get; set; }
        public virtual SubmissionQuestion SubmissionQuestion { get; set; }
}
2
  • No need to do this. You can (and should) add the SubmissionQuestionSubmission to Submission.SubmissionQuestionSubmission and call SaveChanges once. Commented Jun 27, 2020 at 21:48
  • @GertArnold can you advice more on your reply please? Commented Jun 27, 2020 at 23:55

1 Answer 1

1

When SaveChanges() is called it will automatically update the Id field for the new saved entity. As an example, EF might generate queries as follow when saving a new entity:

SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN

INSERT INTO `Author` (`Name`)
VALUES ('test');

SELECT `Id`
FROM `Author`
WHERE ROW_COUNT() = 1
 AND `Id`=LAST_INSERT_ID()

COMMIT

As you see it will run the INSERT INTO query followed by a SELECT query to get the Id of the new inserted row, which will be saved in the Id property.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks for your useful reply,, but i have a question can thisLAST_INSERT_ID() cause the EF to retrieve the wrong Id in a system which has a high number of users executing the same code?
@testtest No, LAST_INSERT_ID() works per connection and EF will use a transaction to insert the new entity and read the new created ID.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.