Open Closed

CrudAppService Child Entity in MultiTenant Scenario missing TenantId #1037


User avatar
0
jarrad78 created

Check the docs before asking a question: https://docs.abp.io/en/commercial/latest/ Check the samples, to see the basic tasks: https://docs.abp.io/en/commercial/latest/samples/index The exact solution to your question may have been answered before, please use the search on the homepage.

  • ABP Framework version: v4.2.1
  • UI type: MVC
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): no
  • Exception message and stack trace:
  • Steps to reproduce the issue:

I have created simple test scenario with the following entity and child entity

Parent Entity     public class SampleTestX : FullAuditedAggregateRoot<Guid>, IMultiTenant     {         public Guid? TenantId { get; set; }         public string TestA { get; set; }         public string TestB { get; set; }         public string TestC { get; set; }         public string TestD { get; set; }

        public ICollection<SampleTestX2> samples { get; set; }

        public SampleTestX()         {

        }

        public SampleTestX(Guid id)         {             Id = id;         }

        public SampleTestX(Guid id, Guid? tenantId, string testA, string testB, string testC, string testD)         {             Id = id;             TenantId = tenantId;             TestA = testA;             TestB = testB;             TestC = testC;             TestD = testD;         }     }

Child Entity     public class SampleTestX2 : FullAuditedEntity<Guid>, IMultiTenant     {         public Guid? TenantId { get; set; }         public string SampleA { get; set; }         public string SampleB { get; set; }

        public Guid SampleTestXId { get; set; } //FK         public SampleTestX sample { get; set; } //Nav Link

        public SampleTestX2()         {

        }

        public SampleTestX2(Guid id, Guid? tenantId)         {             Id = id;             TenantId = tenantId;         }     }

app service interface:     public interface ISampleTestXAppService : ICrudAppService<SampleTestXDto, Guid, PagedAndSortedResultRequestDto, CreateSampleTestXDto, UpdateSampleTestXDto>     {         Task<SampleTestXExtendedDto> GetExtendedAsync(Guid id);     }

app service:     public class SampleTestXAppService : CrudAppService<SampleTestX, SampleTestXDto, Guid, PagedAndSortedResultRequestDto, CreateSampleTestXDto, UpdateSampleTestXDto>, ISampleTestXAppService     {         private IRepository<SampleTestX, Guid> _testRepository;         public SampleTestXAppService(IRepository<SampleTestX, Guid> testRepository) : base(testRepository)         {             _testRepository = testRepository;         }

        public virtual async Task<SampleTestXExtendedDto> GetExtendedAsync(Guid id)         {             var sampleTestX = await GetSampleTestX<SampleTestXExtendedDto>(id, true);             return sampleTestX;         }

        private async Task<TSampleTestXDtoType> GetSampleTestX<TSampleTestXDtoType>(Guid id, bool isExtended = false) where TSampleTestXDtoType : SampleTestXDto         {             var tmp = await _testRepository.GetAsync(id: id, includeDetails: isExtended);             return ObjectMapper.Map<SampleTestX, TSampleTestXDtoType>(tmp);         }     } Repo Interface:     public interface ISampleTestXRepository : IRepository<SampleTestX, Guid>     {

    }

EFCore Repo Implementation:     public class EfCoreSampleTestXRepository : EfCoreRepository<AppDbContext, SampleTestX, Guid>, ISampleTestXRepository     {         public EfCoreSampleTestXRepository(IDbContextProvider<AppDbContext> dbContextProvider) : base(dbContextProvider)         {         }

        public override async Task<IQueryable<SampleTestX>> WithDetailsAsync()         {             // Uses the extension method defined above             return (await GetQueryableAsync()).IncludeDetails();         }     }     public static class SampleTestXExtensionMethods     {         public static IQueryable<SampleTestX> IncludeDetails(this IQueryable<SampleTestX> queryable, bool include = true)         {             if (!include)             {                 return queryable;             }

            return queryable                 .Include(x=>x.samples);         }     }

I want to use CrudAppService to be able to create parent and child entity at same time. Is this possible using CrudAppService in MultiTenant scenario? I am able to successfully create the parent and child entity but the tenantId of child entity is always blank upon creation. If I were to create custom app implementation then injecting ICurrentUser would be no problem but using CrudAppService I do not see where this is possible for child entity. Am I missing something or is this not possible?


5 Answer(s)
  • User Avatar
    0
    jarrad78 created

    I figured out to add TenantId field to DTO object, I then overrode the base crud app service method, I then add TenantId to the DTO prior to sending the updated DTO object to base CRUD method. Is this correct approach?

  • User Avatar
    0
    gterdem created
    Senior .NET Developer

    I figured out to add TenantId field to DTO object, I then overrode the base crud app service method, I then add TenantId to the DTO prior to sending the updated DTO object to base CRUD method. Is this correct approach?

    You can also inject ICurrentTenant to your application service to get the current tenant information.

  • User Avatar
    0
    jarrad78 created

    I figured out to add TenantId field to DTO object, I then overrode the base crud app service method, I then add TenantId to the DTO prior to sending the updated DTO object to base CRUD method. Is this correct approach?

    You can also inject ICurrentTenant to your application service to get the current tenant information.

    I can get the ICurrentTenant without issue, is there any way to have the sub-entities update when using the IRepository UpdateAsync method? Currently when I attempt to update via IRepository UpdateAsync method, the parent entity updates as expected but the attached child entities are all marked as isDeleted = true and none of the updates are applied to the sub-entites upon save. It's strange because when I debug, the results are exactly as expected and show the correct information, but after the resultDTO object is sent back to the browser, then the sub-entities are being marked as deleted in the database.

  • User Avatar
    0
    alper created
    Support Team Director

    you need to do that manually as it's related to EF Core. But I suggest you to create your own appservice and repository because ICrudAppService is for basic (1 entity) CRUD operations. your page is more complex than this.

  • User Avatar
    0
    ServiceBot created
    Support Team Automatic process manager

    This question has been automatically marked as stale because it has not had recent activity.

Made with ❤️ on ABP v9.1.0-preview. Updated on November 19, 2024, 12:56