public async Task<int> CreateOwnerDetailAsync(CreateOrEditOwnerDetailInput input)
{
var ownerDetail = input.OwnerDetail.MapTo<OwnerDetail>();
var ownerDetailId = await _ownerDetailRepository.InsertAndGetIdAsync(ownerDetail);
return ownerDetailId;
}
public async Task<int?> EditOwnerDetailAsync(CreateOrEditOwnerDetailInput input)
{
var ownerDetail = await _ownerDetailRepository.FirstOrDefaultAsync(p => p.Id == input.OwnerDetail.Id);
input.OwnerDetail.MapTo(ownerDetail);
await _ownerDetailRepository.UpdateAsync(ownerDetail);
return input.OwnerDetail.Id;
}
public class CreateOrEditOwnerDetailInput : IInputDto
{
[Required]
public OwnerDetailEditDto OwnerDetail { get; set; }
}
[AutoMap(typeof(OwnerDetail))]
public class OwnerDetailEditDto
{
public const int MaxLength = 50;
public int? Id { get; set; }
[Required]
[MaxLength(MaxLength)]
public string LastName { get; set; }
[Required]
public OwnerContactDetailDto ContactDetail { get; set; }
[Required]
public AdditionalAddressDto AdditionalAddress { get; set; }
}
[Table("IpOwnerDetails")]
public class OwnerDetail : FullAuditedEntity
{
public const int MaxLength = 50;
[Required]
[MaxLength(MaxLength)]
public virtual string LastName { get; set; }
[ForeignKey("AdditionalAddressId")]
public virtual AdditionalAddress AdditionalAddress { get; set; }
public virtual int AdditionalAddressId { get; set; }
[ForeignKey("ContactDetailId")]
public virtual ContactDetail ContactDetail { get; set; }
public virtual int ContactDetailId { get; set; }
}
public class OwnerContactDetailDto : FullAuditedEntityDto
{
public const int NumberMaxLength = 20;
[Required]
[MaxLength(NumberMaxLength)]
public string MainPhoneNumber { get; set; }
[MaxLength(NumberMaxLength)]
public string CellPhoneNumber { get; set; }
}
public class AdditionalAddressDto : FullAuditedEntityDto
{
public const int MaxLength = 50;
[Required]
[MaxLength(MaxLength)]
public string StreetNumber { get; set; }
[Required]
[MaxLength(MaxLength)]
public string StreetName { get; set; }
}
Custom mapping :
private static void CreateMappingsInternal()
{
Mapper.CreateMap<AdditionalAddress, AdditionalAddressDto>()
.ReverseMap()
.ForMember(additionalAddress => additionalAddress.Id, options => options.Ignore());
Mapper.CreateMap<ContactDetail, OwnerContactDetailDto>()
.ReverseMap()
.ForMember(contactDetail => contactDetail.Id, options => options.Ignore());
}
Q : I can create an 'owner detail' by using above code.But when I try to use same "Save" button to edit the record it gives below exception.I have included more details on the attached image.Please see that too.Could you tell me why this is happening ? Thanks in advance.
Note : After this line " input.OwnerDetail.MapTo(ownerDetail);" inside the "EditOwnerDetailAsync()" method where "AdditionalAddress" and "ContactDetail " objects are changed it to "null".Could you tell me why ?
Note 2 : I have used custom mappings hence this error "System.InvalidOperationException: The property 'Id' is part of the object's key information and cannot be modified.".Now that error is not there.But it gives above mentioned error now.
Image : [http://imgur.com/a/GRdw6])
The strange thing here is when I bring the debug pointer back to the " input.OwnerDetail.MapTo(ownerDetail);" line (2nd time) then it fills data for the "AdditionalAddress" and "ContactDetail " objects.How can It be happend ? Please tell me :?:
Exception :
ERROR 2015-11-19 20:58:22,258 [5 ] lers.Filters.AbpExceptionFilterAttribute - System.ArgumentNullException: Value cannot be null.
Parameter name: entity
at System.Data.Entity.Utilities.Check.NotNull[T](T value, String parameterName)
at System.Data.Entity.DbSet`1.Attach(TEntity entity)
at Abp.EntityFramework.Repositories.EfRepositoryBase`3.AttachIfNot(TEntity entity)
at Castle.Proxies.EfRepositoryBase`2Proxy_18.AttachIfNot_callback(AdditionalAddress entity)
at Castle.Proxies.Invocations.EfRepositoryBase`3_AttachIfNot_28.InvokeMethodOnTarget()
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Abp.Domain.Uow.UnitOfWorkInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.EfRepositoryBase`2Proxy_18.AttachIfNot(AdditionalAddress entity)
at Abp.EntityFramework.Repositories.EfRepositoryBase`3.UpdateAsync(TEntity entity)
at Castle.Proxies.EfRepositoryBase`2Proxy_18.UpdateAsync_callback(AdditionalAddress entity)
at Castle.Proxies.Invocations.EfRepositoryBase`3_UpdateAsync_28.InvokeMethodOnTarget()
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Abp.Domain.Uow.UnitOfWorkInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.EfRepositoryBase`2Proxy_18.UpdateAsync(AdditionalAddress entity)
at Joshi.IP.OwnerDetails.OwnerDetailAppService.<EditOwnerDetailAsync>d__e.MoveNext() in d:\Freelance Work\Nipun-SPA\SPA\island\Joshi.IP.Application\OwnerDetails\OwnerDetailAppService.cs:line 65
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Joshi.IP.OwnerDetails.OwnerDetailAppService.<CreateOrEditOwnerDetailAsync>d__0.MoveNext() in d:\Freelance Work\Nipun-SPA\SPA\island\Joshi.IP.Application\OwnerDetails\OwnerDetailAppService.cs:line 34
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Abp.Threading.InternalAsyncHelper.<AwaitTaskWithPostActionAndFinallyAndGetResult>d__10`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Abp.Threading.InternalAsyncHelper.<AwaitTaskWithFinallyAndGetResult>d__c`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__3`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Abp.Extensions.ExceptionExtensions.ReThrow(Exception exception)
at Abp.WebApi.Controllers.Dynamic.Selectors.DynamicHttpActionDescriptor.<ExecuteAsync>b__0(Task`1 task)
at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Controllers.AuthenticationFilterResult.<ExecuteAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()
4 Answer(s)
-
0
Hi,
It seems OwnerDetail.AdditionalAddress and/or OwnerDetail.ContactDetail is null which should not be null. Maybe they are null in DTO? Maybe it's related to lazy-loading of AdditionalAddress and ContactDetail objects. Mapping such deep relations can be proplemation in Entity Framework.
Actually these are our of scope of AspNet Support. Because it's completely about AutoMapper and Entity Framework libraries. We can not support all libraries and general programming problems because it's impossible. AutoMapper has own documentation. I suggest you to search it on the web and read automapper documentation first. Also, you don't have to use AutoMapper for every case, you can just create the entity manually as you can always do.
We try to support even non AspNet Zero related questions, but sometimes it may not be possible, sorry.
-
0
Hi Halil,
Thanks for the reply.Me too think this is due to lazy loading issue.Is there any way to use eager loading with below mentioned query ? Thanks in advance.
var ownerDetail = await _ownerDetailRepository.FirstOrDefaultAsync(p => p.Id == input.OwnerDetail.Id);
Note : I know how to do it in general.But I would like to know how to it with ABP ?
Eager loading sample :
var blog1 = context.Blogs .Where(b => b.Name == "ADO.NET Blog") .Include(b => b.Posts) .FirstOrDefault();
-
0
Hi,
It's not much different for ABP:
_blogRepository.GetAll() .Include(b => b.Posts) .Where(b => b.Name == "ADO.NET Blog") .FirstOrDefault();
Have a nice day.
-
0
Hi Halil,
OK sure. Thanks a lot.You too have a Great week ahead ! :)