Rhetos / Rhetos

Rhetos is a DSL platform, specialized for Enterprise Application Development.
http://www.rhetos.org/
Other
49 stars 34 forks source link

Deleting record from ComputedFromEntity #176

Open ikudeljnj opened 5 years ago

ikudeljnj commented 5 years ago

I have the following case:

Entity WarehouseIncomingReservationState
    {
        AuditAndLoggingAll;

        FilterBy 'Warehouse.IncomingReservationChangeData[]' 
        '(repository, changedItems) =>
            {
                var positionIds = changedItems.Where(x => x.WarehousePositionID.HasValue).Select(changedItem => changedItem.WarehousePositionID.Value).ToList();
                return repository.Warehouse.WarehouseIncomingReservationState.Query().Where(item => positionIds.Contains(item.WarehousePositionID.Value)).ToSimple().ToArray();                
            }
        ';

        ComputedFrom Warehouse.ComputeWarehouseIncomingReservationState
        {
            AllProperties;
            KeepSynchronized;
        }           
    }

SqlQueryable ComputeWarehouseIncomingReservationState <SQL\ComputeWarehouseIncomingReservationState.sql>        
    {   
          Reference Document Warehouse.Document;
          Reference Owner MasterData.Company;
          ShortString Lot;
          Reference DocumentItem Warehouse.DocumentItem;
          ShortString DocumentItemNumber;                
      Reference Project MasterData.Project;
          Reference OfficeLocation MasterData.Company;
          Reference Commodity MasterData.Commodity;
          Reference WareType MasterData.WareType;
          Reference ReceiptItemDetailsEvent Warehouse.ReceiptItemDetailsEvent;
        }

Now, when i try to delete a record from ReceiptItemDetailsEvent table, I get:

The DELETE statement conflicted with the REFERENCE constraint "FK_WarehouseIncomingReservationState_ReceiptItemDetailsEvent_ReceiptItemDetailsEventID".

How do I mitigate this issue?

Regards, Ivan

bantolov commented 5 years ago

We can look at this as a simple entity WarehouseIncomingReservationState, with a reference to ReceiptItemDetailsEvent (copied from the view). that block us from deleting the referenced records.

You can mark this reference with CascadeDelete to automatically delete the related items:

Entity WarehouseIncomingReservationState
{
    ...

    CascadeDelete ReceiptItemDetailsEvent;
}

The full syntax for CascadeDelete usually looks like the this: Reference ReceiptItemDetailsEvent Warehouse.ReceiptItemDetailsEvent { CascadeDelete; }, but the simpler syntax above is better here because we expect the reference property ReceiptItemDetailsEvent to already exist on this entity.

This situation might get more complicated since WarehouseIncomingReservationState is a computed entity, depending on "ChangesOn" definitions, but in most situations the modification above should be enough.

ikudeljnj commented 5 years ago

Will this solution also recompute the computed entity?

bantolov commented 5 years ago

No, CascadeDelete does not trigger recompute on the entity. It will just delete those records in WarehouseIncomingReservationState that reference the deleted records in ReceiptItemDetailsEvent.

If data in WarehouseIncomingReservationState needs to be recomputed when inserting or updating records in ReceiptItemDetailsEvent, then you will need to specify a ChangesOn* rule in SqlQueryable ComputeWarehouseIncomingReservationState. Probably something like this:

SqlQueryable ComputeWarehouseIncomingReservationState ...
{
    ...
    ChangedOnReferenced ReceiptItemDetailsEvent;
}