有些方法应该是属于Entity本身,而不应该写在外面. 写起来比较繁琐而且难以维护. 比如
$taskEntity->run();
$taskEntity->setFinish();
当然以上entity是我自定义. 这里的扩展主要是扩展系统或者第三方模块提供的Entity
/**
 * extends entity class.
 *
 * @param array $entity_types
 */
function mymodule_entity_type_alter(array &$entity_types) {
  /** @var \Drupal\Core\Entity\EntityTypeInterface[] $entity_types */
  $entity_types['node']->setStorageClass('Drupal\mymodule\ArticleNodeStorage');
}
自定一个Storage继承系统的Storage
<?php
namespace Drupal\mymodule;
use Drupal\node\NodeStorage;
class ArticleNodeStorage extends NodeStorage {
  public function getEntityClass(?string $bundle = NULL): string
  {
    return ArticleClass::class;
  }
}
编写ArticleClass继承原EntityClass
<?php
namespace Drupal\mymodule;
use Drupal\node\Entity\Node;
class ArticleClass extends Node {
  public function toggleElasticsearchRef() {
    if ($this->isPublished()) {
      $this->pushToElasticsearch();
    } else {
      $this->deleteToElasticsearch();
    }
  }
  // 将文章推送到Elasticsearch.
  public function pushToElasticsearch() {
    $params = [
      'id' => $this->id(),
      'title' => $this->label(),
      'body' => $this->get('body')->value,
    ];
    (new \Drupal\mymodule\Repository())->index($params);
  }
  // 从Elasticsearch上删除文章.
  public function deleteToElasticsearch() {
    try {
      (new \Drupal\mymodule\Repository())->delete($this->id());
    } catch (\Exception $e) {
    }
  }
}
接下来就可以这样使用了.
$node = \Drupal\node\Entity\Node::load(1);
$node->pushToElasticsearch();
$node->deleteToElasticsearch();
// Entity更新的时候自动检查是否要删除ES索引
function mymodule_entity_update(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity->getEntityTypeId() == 'node' && $entity->bundle() == 'article') {
    $entity->toggleElasticsearchRef();
  }
}
// Entity删除的时候删除Es索引
function mymodule_entity_delete(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity->getEntityTypeId() == 'node' && $entity->bundle() == 'article') {
    $entity->deleteToElasticsearch();
  }
}