Base solution for your next web application
Open Closed

Unity of Work with non-standard entities #4335


User avatar
0
klawsuc created

I have the following classes/tables:

Company : FullAuditedEntity<int>, IPassivable, IExtendableObject
Address : FullAuditedEntity<int>, IPassivable
CompanyAddress

The CompanyAddress class has the companyId, addressId, and an address type..it does not have an entity id like the other classes. I want to be able to add an address and if successful, add an entry into companyAddress. Then commit the changes so that these entries are only saved if they both succeed.

First of all what is the best way to add a record to the non-entity table (CompanyAddress). In the CompanyAppService i added

private readonly IDbContextProvider<DbContext> _contextProvider;

Then in the AddAddress method I have

CompanyAddress ca = new CompanyAddress();
ca.AddressId = addy.Id;
ca.CompanyId = input.CompanyId;
ca.AddressTypeId = input.AddressTypeId;
DbContext dbc = _contextProvider.GetDbContext();
dbc.Add(ca);

Next question, I have an AddressAppService with an insert method. So in the CompanyAppService.AddAddress should I be creating an instance of the AddressAppService and using the insert method to create the address? Or should I just create the record directly like I'm doing with CompanyAddress?

Basically what I am looking to have:

//Create an Address record and get the generated ID
//Insert a record into CompanyAddress
//on success of both, commit the changes to the db
//on failure, cancel saving the address

Should I be using UoW for this or just do an insert of the address and if it succeeds, attempt to add a record to CompanyAddress and if that fails, remove the address?


5 Answer(s)
  • User Avatar
    0
    aaron created
    Support Team

    First of all what is the best way to add a record to the non-entity table (CompanyAddress).

    That looks fine. Is it a many-to-many or one-to-many relationship?

    So in the CompanyAppService.AddAddress should I be creating an instance of the AddressAppService and using the insert method to create the address? Or should I just create the record directly like I'm doing with CompanyAddress?

    You should use a domain service/manager instead. See detailed answers: Should I be calling an AppService from another AppService?.

    Should I be using UoW for this or just do an insert of the address and if it succeeds, attempt to add a record to CompanyAddress and if that fails, remove the address?

    That's a good use case for UnitOfWork. Note that if it's triggered by an AppServicecall, UnitOfWorkis automatically started. Simply throw an exception and ABP will handle the rollback (or commit if there is no exception).

  • User Avatar
    0
    klawsuc created

    Thank you! Addresses are a one-to-many relation (Companies can have many different addresses). But addresses are also used for patients and users which is why I have the CompanyAddress table. I will look at the link.

  • User Avatar
    0
    klawsuc created

    @aaron I read the post but unfortunately I'm not sure what to do with that information. Any sample code or information would be greatly appreciated. I'm fairly new to mvc and structured code...coming from the old aspx pages world. Thanks.

  • User Avatar
    0
    aaron created
    Support Team

    A domain service (conventionally with the Manager postfix, e.g. AddressManager) simply injects the necessary repositories (or DbContextProvider) and performs almost everything you are doing in your AddressAppService. So your AddressAppService is simply a wrapper accessible on client side, that injects AddressManager and calls the methods. Then CompanyAppService injects AddressManager instead of AddressAppService, preserving a clear dependency hierarchy while avoiding duplicate or error-prone code in CompanyAppService to do the same thing.

    For sample code, you can refer to AbpTenantManager.

  • User Avatar
    0
    klawsuc created

    Thanks again. Makes sense. I'll poke around the documentation to see how to actually set that up.