entity-frameworkasp.net-coresavechanges

How to insert child data first and then parent data and child inserted identity using Entity Framework Core


I have a requirement where I need to insert data in child table first then its parent and then child inserted record identity into parent table and this is what I am doing while updating the existing record. lets see the request body :

{
    "StudentId": 111001,
    "StudentName": "Gaurav Singh",
    "Address": 
    [
        {
            "AddressId" : 223344,
            "AddressType": 1,
            "StudentId" : 111001,
            "AddressLine1": "Noida Sec 15",
            "City": "Noida",
            "State": "U.P.",
            "Country": "India",
            "PhoneId":311386
            "PhoneNumber": {
                "PhoneId": 311386,
                "PhoneNumber": "123456789"
            }
        },
        { // this my new entry in database which is not getting inserted.
            "AddressId" : null,
            "AddressType": 2,
            "StudentId" : 111001,
            "AddressLine1": "Noida Sec 18",
            "City": "Noida",
            "State": "U.P.",
            "Country": "India",
            "PhoneId":0
            "PhoneNumber": {
                "PhoneId": NULL,
                "PhoneNumber": "2233445566"
            }
        }
    ]
}

Now in my code I am trying with below code but it is not working while updating existing data but for whole new record it is working fine.

foreach (var _adressData in data.Addresses.ToList())
{
    var _address = _context.Address
                           .Where(p => p.AddressId == _adressData.AddressId)
                           .FirstOrDefault();

    if (_address != null)
    {
        _context.Entry(_address).CurrentValues.SetValues(_adressData);
    }
    else
    {
        var _adr = new Address
        {
            AddressId = null,
            AddressType = 2,
            StudentId = 111001,
            AddressLine1 = "Noida Sec 18",
            City = "Noida",
            State = "U.P.",
            Country = "India",
            PhoneNumber = new PhoneNumberEntity{
                PhoneId = NULL,
                PhoneNumber = "2233445566"
            }
        };

        currentData.Address.Add(_adr);
    }
}

await _context.SaveChangesAsync();
return currentData;

Does anyone have any suggestions?

Clsess are -

public class student {
    public int StudentId {get;set;}
    public string StudentName {get;set;}
    public ICollection<AddressEntity> Addresses {get;set;}}

public class AddressEntity {
    public int StudentId {get;set;}
    public int AddressType {get;set;}
    public int PhoneId {get;set;}
    public string AddressLine1 {get;set;}
    public string City {get;set;}
    public string State {get;set;}
    public string Country {get;set;}
    public PhoneEntity PhoneNumber {get;set;} }

public class PhoneEntity {
    public int PhoneId {get;set;}
    public string PhoneNumber {get;set;} }

Thanks


Solution

  • public class student {
        public int StudentId {get;set;}
        public string StudentName {get;set;}
        public ICollection<AddressEntity> Addresses }
    

    First, for the Student class, try to add get and set methods for the Addresses property.

    public class Student
    {
        public int StudentId { get; set; }
        public string StudentName { get; set; }
        public ICollection<AddressEntity> Addresses { get; set; }
    }
    

    Second, in the Edit Post method, try to refer the following sample to update the model:

       [HttpPost]
        public IActionResult Edit(Student student)
        { 
            //based on the student's StudentId property to find the existing item from the database.
            var existStudent = _context.Students
                .Include(c=>c.Addresses).ThenInclude(c=>c.PhoneNumber)
                .Where(c => c.StudentId == student.StudentId).FirstOrDefault();
    
            //define a list to store the student's address.
            var address = new List<AddressEntity>();
    
            if(existStudent != null)
            {
                //loop through the address list from the student (post parameters).
                foreach (var _adressData in student.Addresses.ToList())
                {
                    //check if the address is exist or not.
                    var _address = _context.Addresses
                                           .Where(p => p.AddressId == _adressData.AddressId)
                                           .FirstOrDefault();
    
                    if (_address != null)
                    {
                        //update the exist address.
                        _context.Entry(_address).CurrentValues.SetValues(_adressData); //update the existing address.
                        //add the existing address to the list.
                        address.Add(_address);
                    }
                    else
                    {
                       //add new address object to the list.
                       address.Add(_adressData);
                    }
                }
                existStudent.Addresses = address; //set address for the student.
            }
            _context.SaveChanges(); //call the SaveChange method 
    
            var latestdata = _context.Students.ToList();
    
            return View();
        }
    

    The result like this (before editing, the existing student contain one Address, after changing, it contains two addresses):

    enter image description here