I found this, very similar to what I try to do in a classic book on Entity Framework programming, but we do not have anyway to use it in ABP, for what I know
private static void SaveDestinationAndLodgings(
Destination destination,
List<Lodging> deletedLodgings)
{
// TODO: Ensure only Destinations & Lodgings are passed in
using (var context = new BreakAwayContext())
{
context.Destinations.Add(destination);
if (destination.DestinationId > 0)
{
context.Entry(destination).State = EntityState.Modified;
}
foreach (var lodging in destination.Lodgings)
{
if (lodging.LodgingId > 0)
{
context.Entry(lodging).State = EntityState.Modified;
}
}
foreach (var lodging in deletedLodgings)
{
context.Entry(lodging).State = EntityState.Deleted;
}
context.SaveChanges();
}
}
Yes it is in application service and here it is last version
[AbpAuthorize(AppPermissions.Pages_Tenant_Partners_CreatePartner)]
public async Task EditPartner(EditPartnerInput input)
{
var partner = input.MapTo<Partner>();
var phones = input.Phones.MapTo<List<Phone>>();
var phonesToDelete = input.DeletedPhones.MapTo<List<Phone>>();
var query = await _partnerRepository.UpdateAsync(partner);
foreach (var phone in phones)
{
if (phone.Id == 0)
{
{
// var currentPartner = _partnerRepository.Get(partner.Id);
// currentPartner.Phones.Add(phone);
//// await CurrentUnitOfWork.SaveChangesAsync();
await _phoneRepository.InsertAsync(phone);
await CurrentUnitOfWork.SaveChangesAsync();
}
}
else
{
var phoneToUpdate = await _phoneRepository.GetAsync(phone.Id);
phone.MapTo(phoneToUpdate);
await _phoneRepository.UpdateAsync(phoneToUpdate);
}
}
foreach (var phoneToDelete in phonesToDelete)
{
await _phoneRepository.DeleteAsync(phoneToDelete.Id);
}
}
No way.... same error.
Should I change my Dto?
I tried both, the commented and uncommented:
using Abp.AutoMapper;
using Abp.Application.Services.Dto;
using System.Collections.ObjectModel;
namespace stake.Partners.Dto
{
[AutoMapTo(typeof(Partner))]
public class EditPartnerInput : IInputDto
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
//public Collection<PhoneInEditPartnerDto> Phones { get; set; }
public PartnerPhoneDto[] Phones { get; set; }
public PartnerPhoneDto[] DeletedPhones { get; set; }
}
//[AutoMapTo(typeof(Phone))]
//public class PhoneInEditPartnerDto : EntityDto
//{
// public string Name { get; set; }
// public int PartnerId { get; set; }
// public int PhoneTypeId { get; set; }
//}
}
The phone Dto is:
using Abp.AutoMapper;
using Abp.Application.Services.Dto;
namespace stake.Partners.Dto
{
[AutoMap(typeof(Phone))]
public class PartnerPhoneDto : EntityDto
{
public string Name { get; set; }
public int PartnerId { get; set; }
public int PhoneTypeId { get; set; }
}
}
I would say yes, as I made so many attempts, but I try it again and I tell you.
Hi,
I am trying to make multiple addition to a collection at the same time, but it is failing.
Situation is:
The client send a partner (main entity) with phones (or other elements) as a collection. There are 3 cases, the phone has been deleted and it is in a deleted phones list, the phone has been modified or added. I identify the new phones because they have a 0 id so I build the following application service:
[AbpAuthorize(AppPermissions.Pages_Tenant_Partners_CreatePartner)]
public async Task EditPartner(EditPartnerInput input)
{
var partner = input.MapTo<Partner>();
var phones = input.Phones.MapTo<List<Phone>>();
var phonesToDelete = input.DeletedPhones.MapTo<List<Phone>>();
var query = await _partnerRepository.UpdateAsync(partner);
foreach (var phone in phones)
{
if (phone.Id == 0)
{
{
var currentPartner = _partnerRepository.Get(partner.Id);
currentPartner.Phones.Add(phone);
// await CurrentUnitOfWork.SaveChangesAsync();
}
}
else
{
var phoneToUpdate = await _phoneRepository.GetAsync(phone.Id);
phone.MapTo(phoneToUpdate);
await _phoneRepository.UpdateAsync(phoneToUpdate);
}
}
foreach (var phoneToDelete in phonesToDelete)
{
await _phoneRepository.DeleteAsync(phoneToDelete.Id);
}
}
Everything is working fine:
BUT
if I have more than one phone to add I get the following error:
System.InvalidOperationException: Attaching an entity of type 'stake.Partners.Phone' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.
This is obviously related to the fact that the first record is not yet saved when the second one is processed. The suggestion is to use Add, and I am using it!
What I tried:
It seems I should change the state of the item, but I did not find the way.
Please help, thanks!
I was using those, but probably I had issues with my Dtos. Now Everything is working fine. Thanks!
Hi,
I have multiple tables with values I want to make appear in dropdown menus in the client during creation or update of entities. Typical case is phonetype for phones. Practically, I should not send anything from the client, just retrieve the complete list of items. I was thinking to use GetAll() or GetAllList() or GetAllListAsync(), but there is no way. I have to give an input and the input it is not to be null.
Can you help me? This is a requirement I have for a lot of items.
Thanks
I confirm the issue on that part is that you have to replace $modal with $uibModal in both the modal controller and the index one. Look at:
$modal has been renamed to $uibModal in ui-bootstrap 0.14.0: [https://github.com/olov/ng-annotate/issues/200])