Search code examples
.netasp.net-mvcentity-frameworkentity-framework-6

How to update the records along with ICollection EF


Without ICollection, I am able to update the data, but my attempts to update the ICollection records fail.

I tried the code shown here, but I get an error

one or more of the foreign-key properties is non-nullable

I need to update the child records, and if records are not there, I need to insert them. Or we can delete and then insert. Please help - what did I do wrong?

FHASMstBank is the entity:

public partial class FHASMstBank
{
    public FHASMstBank()
    {
        this.FHASMstBankDomains = new HashSet<FHASMstBankDomain>();
        this.FHASMstBankProducts = new HashSet<FHASMstBankProducts>();
    }

    [Key]
    public short BankId { get; set; }
    public string BankName { get; set; }
    public string BankCode { get; set; }
    public string BankDescription { get; set; }
    public bool IsActive { get; set; }

    public virtual ICollection<FHASMstBankDomain> FHASMstBankDomains { get; set; }
    public virtual ICollection<FHASMstBankProducts> FHASMstBankProducts { get; set; }
}

This is my UpdateBank method. I'm passing the parameter as bank with updated values:

 public CreateBankResponse UpdateBank(Bank bank)
 {
     try
     {
         var mapper = _mapper.Map<FHASMstBank>(bank);
         var entity = _context.Set<FHASMstBank>().Local.FirstOrDefault(entry => entry.intBankID.Equals(bank.intBankID));

         entity.txtBankName = bank.txtBankName;
         entity.txtBankCode = bank.txtBankCode;
         entity.txtBankDescription = bank.txtBankDescription;
         entity.flgIsActive = bank.flgIsActive;
         entity.dtValidFrom = bank.dtValidFrom;
         entity.txtCreatedBy = bank.txtCreatedBy;
         entity.dtCreatedOn = bank.dtCreatedOn;
         entity.txtModifiedBy = bank.txtModifiedBy;
         entity.dtModifiedOn = bank.dtModifiedOn;
         entity.txtBankGroup = bank.txtBankGroup;
         entity.FHASMstBankDomains = bank.FHASMstBankDomains; //Icollection records
         entity.FHASMstBankProducts  = bank.FHASMstBankProducts;//Icollection records

         if (entity != null) // I'm using an extension method
         {
             // detach
             _context.Entry(entity).State = EntityState.Detached;
         }

         // set Modified flag in your entry
         _context.Entry(entity).State = EntityState.Modified;

         // save 
         var result = _context.SaveChanges(); // Getting error while saving

         if (result > 0)
         {
             return new CreateBankResponse(entity.intBankID, entity.txtBankName, entity.txtBankCode, true, null);
         }
         else
         {
             return new CreateBankResponse(entity.intBankID, entity.txtBankName, entity.txtBankCode, false, new string[] { "Bank Registration failed." });
         }
     }
     catch (DbUpdateException e)
     {
         return new CreateBankResponse(0, string.Empty, string.Empty, false, new string[] { e.Message, e.InnerException.Message });
     }
     catch (DbEntityValidationException e)
     {
         return new CreateBankResponse(0, string.Empty, string.Empty, false, new string[] { e.Message, e.InnerException.Message });
     }
 }

Solution

  • I fixed by below code.

         public CreateBankResponse UpdateBank(Bank bank)
     {
    
         try
         {
             var mapper = _mapper.Map<FHASMstBank>(bank);
             var entityParent = _context.Set<FHASMstBank>().Local.FirstOrDefault(entry => entry.intBankID.Equals(bank.intBankID));
             entityParent.txtBankName = bank.txtBankName;
             entityParent.txtBankCode = bank.txtBankCode;
             entityParent.txtBankDescription = bank.txtBankDescription;
             entityParent.flgIsActive = bank.flgIsActive;
             entityParent.dtValidFrom = bank.dtValidFrom;
             entityParent.txtCreatedBy = bank.txtCreatedBy;
             entityParent.dtCreatedOn = bank.dtCreatedOn;
             entityParent.txtModifiedBy = bank.txtModifiedBy;
             entityParent.dtModifiedOn = bank.dtModifiedOn;
             entityParent.txtBankGroup = bank.txtBankGroup;
    
             if (entityParent != null)
             {
                 // Update parent
                 _context.Entry(entityParent).CurrentValues.SetValues(bank);
                 // Delete Geo children
                 foreach (var existingChild in entityParent.FHASMstBankGeoMappings.ToList())
                 {
                     if (!bank.FHASMstBankGeoMappings.Any(c => c.intID == existingChild.intID))
                         _context.FHASMstBankGeoMappings.Remove(existingChild);
                 }
                 // Insert Geo children
                 foreach (var childModel in bank.FHASMstBankGeoMappings)
                 {
                     _context.FHASMstBankGeoMappings.Add(childModel);
                 }
    
                 // Delete Domain children
                 foreach (var existingChild in entityParent.FHASMstBankDomains.ToList())
                 {
                     if (!bank.FHASMstBankDomains.Any(c => c.intDomainID == existingChild.intDomainID))
                         _context.FHASMstBankDomains.Remove(existingChild);
                 }
                 // Insert Domain children
                 foreach (var childModel in bank.FHASMstBankDomains)
                 {
                     _context.FHASMstBankDomains.Add(childModel);
                 }
    
                 // Delete Products children
                 foreach (var existingChild in entityParent.FHASMstBankProducts.ToList())
                 {
                     if (!bank.FHASMstBankProducts.Any(c => c.intBankProductsID == existingChild.intBankProductsID))
                         _context.FHASMstBankProducts.Remove(existingChild);
                 }
                 // Insert Products children
                 foreach (var childModel in bank.FHASMstBankProducts)
                 {
                     _context.FHASMstBankProducts.Add(childModel);
                 }
    
                 // Delete Components children
                 foreach (var existingChild in entityParent.FHASMstBankComponents.ToList())
                 {
                     if (!bank.FHASMstBankComponents.Any(c => c.intBankComponentID == existingChild.intBankComponentID))
                         _context.FHASMstBankComponents.Remove(existingChild);
                 }
                 // Insert Components children
                 foreach (var childModel in bank.FHASMstBankComponents)
                 {
                     _context.FHASMstBankComponents.Add(childModel);
                 }
    
             }
    
             // save 
             var result = _context.SaveChanges();
    
             if (result > 0)
             {
                 return new CreateBankResponse(entityParent.intBankID, entityParent.txtBankName, entityParent.txtBankCode, true, null);
    
             }
             else
             {
                 return new CreateBankResponse(entityParent.intBankID, entityParent.txtBankName, entityParent.txtBankCode, false, new string[] { "Bank Registration failed." });
    
             }
         }
         catch (DbUpdateException e)
         {
             return new CreateBankResponse(0, string.Empty, string.Empty, false, new string[] { e.Message, e.InnerException.Message });
    
         }
         catch (DbEntityValidationException e)
         {
             return new CreateBankResponse(0, string.Empty, string.Empty, false, new string[] { e.Message, e.InnerException.Message });
         }
    
    
     }