public virtual void UpdateGraphWithChildDeletes(ProductLineEntity productLine)
        {
            if (productLine == null)
            {
                throw new ArgumentNullException(nameof(productLine), $"{nameof(productLine)} is null.");
            }

            // this update method will update the related products. Any removed product has to be removed as it's orphaned.
            // We have to remove all products which key isn't in the set of products currently related to the passed in productline.
            // To do that we'll do a delete directly using a where clause where all entities with a key not in the set of
            // keys of the current related product entities are removed. We'll wrap it all in a unit of work for easy transaction handling.
            // In the unit of work, we have to schedule the direct deletes before the insert of the new row, otherwise it's removed,
            // as it doesn't have a PK yet, so the IN clause we're using won't match it.
            var currentKeys = productLine.Products.Select(p => p.ProductKey).ToList();
            var uow         = new UnitOfWork2(new List <UnitOfWorkBlockType>()
            {
                UnitOfWorkBlockType.DeletesPerformedDirectly,
                UnitOfWorkBlockType.Inserts,
                UnitOfWorkBlockType.Updates
            });

            uow.AddDeleteEntitiesDirectlyCall(typeof(ProductEntity), new RelationPredicateBucket(ProductFields.ProductKey.NotIn(currentKeys)));
            uow.AddForSave(productLine);
            using (var adapter = new DataAccessAdapter())
            {
                uow.Commit(adapter);
            }
        }
        public void DeleteByKey(int productLineKey)
        {
            // let's directly delete the entities, without fetching them. Use a unit of work for this
            // to wrap everything neatly in a transaction when it's committed. A Unit of work is a
            // persistence agnostic object you can pass on freely to add work and then have all the work
            // performed in a single transaction.
            var uow = new UnitOfWork2();

            uow.AddDeleteEntitiesDirectlyCall(typeof(ProductEntity),
                                              new RelationPredicateBucket(ProductFields.ProductLineKey.Equal(productLineKey)));
            uow.AddDeleteEntitiesDirectlyCall(typeof(ProductLineEntity),
                                              new RelationPredicateBucket(ProductLineFields.ProductLineKey.Equal(productLineKey)));
            using (var adapter = new DataAccessAdapter())
            {
                uow.Commit(adapter);
            }
        }
        public void UpdateGraphWithDeletes(ProductLineEntity productLine, IList <int> productKeysToRemove)
        {
            if (productLine == null)
            {
                throw new ArgumentNullException(nameof(productLine), $"{nameof(productLine)} is null.");
            }

            var uow = new UnitOfWork2(new List <UnitOfWorkBlockType>()
            {
                UnitOfWorkBlockType.DeletesPerformedDirectly,
                UnitOfWorkBlockType.Inserts,
                UnitOfWorkBlockType.Updates
            });

            if (productKeysToRemove?.Count > 0)
            {
                uow.AddDeleteEntitiesDirectlyCall(typeof(ProductEntity), new RelationPredicateBucket(ProductFields.ProductKey.In(productKeysToRemove)));
            }
            uow.AddForSave(productLine);
            using (var adapter = new DataAccessAdapter())
            {
                uow.Commit(adapter);
            }
        }