Base solution for your next web application
Open Closed

Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. #6254


User avatar
0
defacto created

I'm trying to simply update navigation properties of an entity but i couldn't succeed. I did a some seaching on the internet but those solution didn't work for me. i actually solved this easy-looking problem but the way i solved it did not satisfy me.

Here is an appropriate forum post and answer by @ismcagdas. Here is an appropriate sof question.

Error message.

ERROR 2019-01-08 08:52:34,428 [86 ] Mvc.ExceptionHandling.AbpExceptionFilter - An error occurred while updating the entries. See the inner exception for details. Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Cannot insert explicit value for identity column in table 'ObjectiveToleranceLimits' when IDENTITY_INSERT is set to OFF. at System.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__122_0(Task`1 result)

Our simlified entities and dtos.

[Table ("Objectives", Schema = "Apl")]
  [Audited]
  public class Objective : FullAuditedEntity&lt;long&gt;, IMayHaveTenant {
      public int? TenantId { get; set; }

      [Required]
      public string Name { get; set; }

      public ICollection&lt;ObjectiveToleranceLimit&gt; ToleranceLimits { get; set; }
  }
 [Table ("ObjectiveToleranceLimits", Schema = "Apl")]
  [Audited]
  public class ObjectiveToleranceLimit : Entity&lt;long&gt;, IMayHaveTenant {
      public int? TenantId { get; set; }

      public int? ToleranceLimit { get; set; }

      [CanBeNull]
      [ForeignKey (nameof (ObjectiveId))]
      public long? ObjectiveId { get; set; }
      public Objective Objective { get; set; }
  }
public class CreateOrEditObjectiveDto : EntityDto&lt;long?&gt; {
      [Required]
      public string Name { get; set; }

      public IList&lt;CreateOrEditObjectiveToleranceLimitDto&gt; ToleranceLimits { get; set; }
  }
public class CreateOrEditObjectiveToleranceLimitDto : EntityDto&lt;long?&gt; {
      public int? ToleranceLimit { get; set; }

      public long? ObjectiveId { get; set; }
  }
 [AbpAuthorize (AppPermissions.Pages_PerformanceManagement_Objectives_Edit)]
  private async Task Update (CreateOrEditObjectiveDto input) {
      var objective = await _objectiveRepository.FirstOrDefaultAsync ((long) input.Id);
      ObjectMapper.Map (input, objective);

      await _objectiveRepository.UpdateAsync (objective);

      // How to make it work?

      // Step#1
      // igone ToleranceLimits mapping in CustomDtoMapper.cs 
      //   configuration.CreateMap&lt;CreateOrEditObjectiveDto, Objective&gt; ()
      //       .ForMember (dto => dto.ToleranceLimits, options => options.Ignore ());

      // Step#2
      // do a manual update
      //   foreach (var toleranceLimitDto in input.ToleranceLimits) {
      //       await _objectiveToleranceLimitRepository.UpdateAsync (
      //           ObjectMapper.Map&lt;ObjectiveToleranceLimit&gt; (toleranceLimitDto));
      //   }
  }

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

    Why not update the ObjectiveToleranceLimit with a new method?

    If you want to update in the Update method, You first need to query the relevant ObjectiveToleranceLimit.

  • User Avatar
    0
    defacto created

    Dear friend, thanks for your reply. Below is my insert method and it works with navigation props.

    [AbpAuthorize (AppPermissions.Pages_PerformanceManagement_Objectives_Create)]
    private async Task Create (CreateOrEditObjectiveDto input) {
        var objective = ObjectMapper.Map<Objective> (input);
    
        if (AbpSession.TenantId != null)
            objective.TenantId = AbpSession.TenantId;
    
        await _objectiveRepository.InsertAsync (objective);
    }
    

    Problem is with update method for navigation props. I thought i did something wrong and that's why i'm having this problem. I refactored my code as you recommended, below it is. But i'm totally not sure if it's good practice. There should be a native support for this. If i can find, i will share it with you.

    [AbpAuthorize(AppPermissions.Pages_PerformanceManagement_Objectives_Edit)]
    private async Task Update(CreateOrEditObjectiveDto input)
    {
        var objective = await _objectiveRepository.FirstOrDefaultAsync((long)input.Id);
        ObjectMapper.Map(input, objective);
    
        await _objectiveRepository.UpdateAsync(objective);
    
        await UpdateToleranceLimits(input);
    }
    
    [AbpAuthorize(AppPermissions.Pages_PerformanceManagement_Objectives_Edit)]
    private async Task UpdateToleranceLimits(CreateOrEditObjectiveDto input)
    {
        foreach (var toleranceLimitDto in input.ToleranceLimits)
            await _objectiveToleranceLimitRepository.UpdateAsync(
                ObjectMapper.Map<ObjectiveToleranceLimit>(toleranceLimitDto));
    }
    

    If you want to update in the Update method, You first need to query the relevant ObjectiveToleranceLimit.

    Could you please show me how to do it?

  • User Avatar
    1
    maliming created
    Support Team

    You can refer to the code of zero:

    https://github.com/aspnetzero/aspnet-zero-core/blob/4d320b11bedbd0628c1332b1d223e76df8fe27be/aspnet-core/src/MyCompanyName.AbpZeroTemplate.Application/Authorization/Roles/RoleAppService.cs#L95

    https://github.com/aspnetzero/aspnet-zero-core/blob/29212eb9058eeef8380e83ac1d216a747d3d06d6/aspnet-core/src/MyCompanyName.AbpZeroTemplate.Application/Editions/EditionAppService.cs#L194

  • User Avatar
    0
    defacto created

    Thanks bro!