Aaron, Once again I am in your debt. I'm not a great coder and at some stage I will sit down and try understand the details. To close the issue I include the finished code below, I am sure this is a very common use case.
public void Create()
{
var root = _context.OrganizationUnits.IgnoreQueryFilters().FirstOrDefault(m => m.TenantId == _tenantId && m.DisplayName == "Acme Care Home");
if (root == null)
{
using (var organizationUnitManager = IocManager.Instance.ResolveAsDisposable<OrganizationUnitManager>())
{
organizationUnitManager.Object.Create(new OrganizationUnit(_tenantId, "Acme Care Home", null));
}
}
_context.SaveChanges();
root = _context.OrganizationUnits.IgnoreQueryFilters().FirstOrDefault(m => m.TenantId == _tenantId && m.DisplayName == "Acme Care Home");
using (var scope = IocManager.Instance.CreateScope())
{
var organizationUnitManager = scope.Resolve<OrganizationUnitManager>();
var unitOfWorkManager = scope.Resolve<IUnitOfWorkManager>();
using (unitOfWorkManager.Current.DisableFilter(AbpDataFilters.MayHaveTenant))
{
var admissions = _context.OrganizationUnits.IgnoreQueryFilters().FirstOrDefault(m => m.TenantId == _tenantId && m.DisplayName == "Admissions");
if (admissions == null)
{
organizationUnitManager.Create(new OrganizationUnit(_tenantId, "Admissions", root.Id));
}
var firstFloor = _context.OrganizationUnits.IgnoreQueryFilters().FirstOrDefault(m => m.TenantId == _tenantId && m.DisplayName == "First Floor");
if (firstFloor == null)
{
organizationUnitManager.Create(new OrganizationUnit(_tenantId, "First Floor", root.Id));
}
var secondFloor = _context.OrganizationUnits.IgnoreQueryFilters().FirstOrDefault(m => m.TenantId == _tenantId && m.DisplayName == "Second Floor");
if (secondFloor == null)
{
organizationUnitManager.Create(new OrganizationUnit(_tenantId, "Second Floor", root.Id));
}
}
}
}
Thanks again.
Wow, Aaron, thanks for the speedy reply, I kind of had this set aside until Monday! The error is unusual, here is a screen capture from VS 2017: [attachment=0:191pkgx2]Capture.PNG[/attachment:191pkgx2] No error is thrown in the log (I don't think the system has hit the logger at this stage if I'm not mistaken). The root organization unit exists in the database (from a previous run). The stack trace reads:
" at Abp.Domain.Repositories.AbpRepositoryBase`2.<GetAsync>d__21.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Abp.Threading.InternalAsyncHelper.<AwaitTaskWithPostActionAndFinallyAndGetResult>d__5`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Abp.Organizations.OrganizationUnitManager.<GetCodeAsync>d__9.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Abp.Organizations.OrganizationUnitManager.<GetNextChildCodeAsync>d__7.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Abp.Organizations.OrganizationUnitManager.<CreateAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Abp.Threading.InternalAsyncHelper.<AwaitTaskWithPostActionAndFinally>d__1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task task)\r\n at Nito.AsyncEx.AsyncContext.<>c__DisplayClass15_0.<Run>b__0(Task t)\r\n at System.Threading.Tasks.ContinuationTaskFromTask.InnerInvoke()\r\n at System.Threading.Tasks.Task.Execute()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task task)\r\n at Nito.AsyncEx.AsyncContext.Run(Func`1 action)\r\n at Abp.Organizations.OrganizationUnitManagerExtensions.Create(OrganizationUnitManager manager, OrganizationUnit organizationUnit)\r\n at Nuagecare.Migrations.Seed.Tenants.InitialChildOrganizationUnitCreator.Create()\r\n at Nuagecare.Migrations.Seed.Tenants.DefaultTenantDataBuilder.CreateChildTables()\r\n at Nuagecare.Migrations.Seed.Tenants.DefaultTenantDataBuilder.Create()\r\n at Nuagecare.Migrations.Seed.SeedHelper.SeedHostDb(NuagecareDbContext context)\r\n at Nuagecare.Migrations.Seed.SeedHelper.WithDbContext[TDbContext](IIocResolver iocResolver, Action`1 contextAction)\r\n at Nuagecare.Migrations.Seed.SeedHelper.SeedHostDb(IIocResolver iocResolver)\r\n at Nuagecare.EntityFrameworkCore.NuagecareEntityFrameworkCoreModule.PostInitialize()\r\n at Abp.Modules.AbpModuleManager.<>c.<StartModules>b__15_2(AbpModuleInfo module)\r\n at System.Collections.Generic.List`1.ForEach(Action`1 action)\r\n at Abp.Modules.AbpModuleManager.StartModules()\r\n at Abp.AbpBootstrapper.Initialize()"
@aaron - thanks, another piece of magic pulled from the magician's hat!!!! But before you light up that cigar can you tell me why the following code in my InitialOrganizationUnitCreator class fails when trying to add a child organization unit?
public void Create()
{
var root = _context.OrganizationUnits.IgnoreQueryFilters().FirstOrDefault(m => m.TenantId == _tenantId && m.DisplayName == "Acme Care Home");
if (root == null)
{
using (var organizationUnitManager = IocManager.Instance.ResolveAsDisposable<OrganizationUnitManager>())
{
organizationUnitManager.Object.Create(new OrganizationUnit(_tenantId, "Acme Care Home", null));
}
}
_context.SaveChanges();
root = _context.OrganizationUnits.IgnoreQueryFilters().FirstOrDefault(m => m.TenantId == _tenantId && m.DisplayName == "Acme Care Home");
var admissions = _context.OrganizationUnits.IgnoreQueryFilters().FirstOrDefault(m => m.TenantId == _tenantId && m.DisplayName == "Admissions");
if (admissions == null)
{
using (var organizationUnitManager = IocManager.Instance.ResolveAsDisposable<OrganizationUnitManager>())
{
organizationUnitManager.Object.Create(new OrganizationUnit(_tenantId, "Admissions", root.Id));
}
}
}
Jeepers, @ jollyticket - aspnetzero is PERFECT for no-sql databases. Serialisation of EntityHistory gives you the initial document and every change thereafter gives an additional document. You could even throw the the serialised result on to a command bus to give you CQRS. If the result of your project has to be a Mongodb database (and I can understand why that may be) and the start point has to be aspnetzero then this is the way to go. Leave the relational database where it is, it is serving the purpose it is designed for. Don't re-invent the wheel.
... and don't over-engineer.
Good luck on that deadline, I hope it all works out for you!
I am having problems creating OrganizationUnits when seeding the project.
SeedHelper is a static class so I can not inject a repository, the appservice or the manager.
Inserting using the context is not possible because the entity requires a value for Code.
There is the possibility of adding project dependencies but this would break all separation of concerns.
My question is:
How do I create OrganizationUnits during seeding?
@jollyticket - If you want all of your data in Mongodb why not cut into EntityHistory functionality and serialize the results using the .net Mongodb driver? That way all of your data will be in Mongodb and your relational stuff will be where it should be, in a relational database? Just a suggestion but it may give you a different direction of thinking because I think you will be pulling your hair out trying to get a system out with an unsupported solution????
@faisalalam - have you tried un-checking the "Add migration" checkbox? Then make the adjustments, including foreign keys, to your entities. Add a migration manually and then update-database. Refresh the swagger interface and you should be good to go. Sorry if this is not appropriate but this is what I do with the aspnet-core/angular project. Hope this helps, if not I'll try to butt-out in the future!
@ismcagdas - thanks for this, I knew I had seen it previously in the forum but was unable to find it. In my solution I create a master component which controls navigation between list, read and create-or-update components.
master
--list
--details
--createorupdate
I implement the code you showed me into the master component and the job is done. Thanks for all your help, this can be closed!
aspnet-core, angular: 5.2.0 I have implemented the Primeng datatable with the dropdown menu template as per your templates. Rather than implementing a modal I am redirecting to a new page. When the new page is displayed the drop-down menu remains in place. Select: [attachment=1:2cc9kuts]Capture.PNG[/attachment:2cc9kuts] Next page: [attachment=0:2cc9kuts]Capture1.PNG[/attachment:2cc9kuts] My component layout is: mainComponent --ListComponent --ReadComponent --CreateOrEditComponent My question is:
How do I remove the drop-down menu?
The version of the RAD tool in 5.2.0 offers the capability to modify client templates. Which is great but it will only create the two components in the angular FileTemplates folder. I tried to add a third template in this folder but it was ignored by the generator. Would it be possible to modify generation code to iterate through this folder and create a folder for the ComponentTemplate.txt (as it currently does) and then a sub-folder within this folder for each of the additional component templates? Thus for my own structure we would have:
component
--list-component
--create-or-update-component
--read-component
I don't think this would be a large change and it would give support to those of who do not like CRUD operations in modals and would also give us a details page for viewing related information. In addition the generation tool, carefully used, could also be used to generate client code for different platforms. For me I can see how I could use this for generation of code for the Ionic platform.