Base solution for your next web application
Open Closed

Updating Only Columns that have changed #8216


User avatar
0
Jayesh created

I use the following method to update the data from the Input received from the Angular UI.

public async Task CreateOrEdit(CreateOrEditOwnerDto input) { var owner = ObjectMapper.Map<Owner>(input); await _ownerRepository.UpdateAsync(owner); }

The above method updates all columns in the Owner table even if I only changed one column from the UI. This is very inefficient for a table with lots of columns.

How do I update only columns that have changed?


8 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team

    Please share the code of the Owner entity and CreateOrEditOwnerDto.


    A general way to update an entity might be as follows:

    public async Task CreateOrEdit(CreateOrEditOwnerDto input)
    {
    	if(input.Id != null) //update
    	{
    		var owner = await _ownerRepository.GetAsync(input.Id);
    		ObjectMapper.Map(input, owner); //or owner.xx = input.xx
    		await _ownerRepository.UpdateAsync(owner);
    	}
    	else //create
    	{
    		//...
    	}
    }
    
  • User Avatar
    0
    sumitshah created

    Owner Entity

    namespace Infogroup.IDMS.Owners
    {
        [Table("tblOwner")]
        public class Owner : Entity 
        {
    
            [Required]
            public virtual string cCode { get; set; }
    
            [Required]
            public virtual string cCompany { get; set; }
    
            [Required]
            public virtual string cAddress1 { get; set; }
    
            [Required]
            public virtual string cAddress2 { get; set; }
    
            [Required]
            public virtual string cCity { get; set; }
    
            [Required]
            public virtual string cState { get; set; }
    
            [Required]
            public virtual string cZip { get; set; }
    
            [Required]
            public virtual string cPhone { get; set; }
    
            [Required]
            public virtual string cFax { get; set; }
    
            [Required]
            public virtual string cNotes { get; set; }
    
            [Required]
            public virtual bool iIsActive { get; set; }
    
            [Required]
            public virtual DateTime dCreatedDate { get; set; }
    
            [Required]
            public virtual string cCreatedBy { get; set; }
    
            public virtual string cModifiedBy { get; set; }
    
            public virtual DateTime? dModifiedDate { get; set; }
    
    
            public virtual int DatabaseId { get; set; }
    
            [ForeignKey("DatabaseId")]
            public Database DatabaseFk { get; set; }
    		
        }
    }
    

    CreateOrEditOwnerDto

    namespace Infogroup.IDMS.Owners.Dtos
    {
        public class CreateOrEditOwnerDto : EntityDto<int?>
        {
    
                public string cCode { get; set; }
    
                public string cCompany { get; set; }
    
                public string cAddress1 { get; set; }
    
                public string cAddress2 { get; set; }
    
                public string cCity { get; set; }
    
                public string cState { get; set; }
    
                public string cZip { get; set; }
    
                public string cPhone { get; set; }
    
                public string cFax { get; set; }
    
                public string cNotes { get; set; }
    
                public bool iIsActive { get; set; }
    
                public int DatabaseId { get; set; }
    
                public string cCreatedBy { get; set; }
    
                public string cModifiedBy { get; set; }
    
                public DateTime dCreatedDate { get; set; }
        }
    }
    
  • User Avatar
    0
    maliming created
    Support Team

    hi

    You can try the following code

    public async Task CreateOrEdit(CreateOrEditOwnerDto input)
    {
            var owner = await _ownerRepository.GetAsync(input.Id);
            ObjectMapper.Map(input, owner); //or owner.xx = input.xx
            CurrentUnitOfWork.SaveChanges();
    }
    
  • User Avatar
    0
    Jayesh created

    Thanks for the reply but this adds an addition call back to the server to fetch the row before updating.

  • User Avatar
    0
    maliming created
    Support Team

    but this adds an addition call back to the server to fetch the row before updating.

    The usual way to use EF is to query the entity before updating it.

    This way EF can track changes to this entity.

    You can check the abp framework or zero built-in code, this is the way.

  • User Avatar
    0
    Jayesh created

    If you query the entity before saving, concurrency is lost. Imagine where record is updated by one user while other user is making changes to the same record. When 2nd user clicks on Save, he is unware of the changed made by 1st user and overrides his changes.

    Instead, what I expect to have happened is that 2nd user gets a concurrency exception that data has been modified after it was loaded in DOM.

  • User Avatar
    0
    maliming created
    Support Team

    hi @jayesh

    The actual situation is exactly the opposite of what you said. For details, you can check the following documents.

    https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/concurrency?view=aspnetcore-3.1#update-edit-methods https://docs.microsoft.com/en-us/ef/core/saving/concurrency#how-concurrency-control-works-in-ef-core

  • User Avatar
    0
    ismcagdas created
    Support Team

    This issue is closed because it has not had recent activity for a long time.