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<long>, IMayHaveTenant {
public int? TenantId { get; set; }
[Required]
public string Name { get; set; }
public ICollection<ObjectiveToleranceLimit> ToleranceLimits { get; set; }
}
[Table ("ObjectiveToleranceLimits", Schema = "Apl")]
[Audited]
public class ObjectiveToleranceLimit : Entity<long>, 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<long?> {
[Required]
public string Name { get; set; }
public IList<CreateOrEditObjectiveToleranceLimitDto> ToleranceLimits { get; set; }
}
public class CreateOrEditObjectiveToleranceLimitDto : EntityDto<long?> {
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<CreateOrEditObjectiveDto, Objective> ()
// .ForMember (dto => dto.ToleranceLimits, options => options.Ignore ());
// Step#2
// do a manual update
// foreach (var toleranceLimitDto in input.ToleranceLimits) {
// await _objectiveToleranceLimitRepository.UpdateAsync (
// ObjectMapper.Map<ObjectiveToleranceLimit> (toleranceLimitDto));
// }
}
4 Answer(s)
-
0
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.
-
0
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?
-
1
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
-
0
Thanks bro!