I could easily be wrong, but I think it depends on the entity with which you are working. Take a couple references from the core, e.g.:
\Magento\Eav\Model\Entity\Collection\AbstractCollection::delete()
public function delete()
{
foreach ($this->getItems() as $key => $item) {
$this->getEntity()->delete($item);
unset($this->_items[$key]);
}
return $this;
}
\Magento\Customer\Controller\Adminhtml\Index\MassDelete::massAction()
:
protected function massAction(AbstractCollection $collection)
{
$customersDeleted = 0;
foreach ($collection->getAllIds() as $customerId) {
$this->customerRepository->deleteById($customerId);
$customersDeleted++;
}
//snip...
}
\Magento\Catalog\Controller\Adminhtml\Product\MassDelete::execute()
public function execute()
{
$collection = $this->filter->getCollection($this->collectionFactory->create());
$productDeleted = 0;
foreach ($collection->getItems() as $product) {
$product->delete();
$productDeleted++;
}
$this->messageManager->addSuccess(
__('A total of %1 record(s) have been deleted.', $productDeleted)
);
return $this->resultFactory->create(ResultFactory::TYPE_REDIRECT)->setPath('catalog/*/index');
}
It comes down to whether there is a service layer setup for the entity.