diff --git a/core/modules/views/src/EntityViewsData.php b/core/modules/views/src/EntityViewsData.php
index cc7b7be..8a9a61e 100644
--- a/core/modules/views/src/EntityViewsData.php
+++ b/core/modules/views/src/EntityViewsData.php
@@ -58,6 +58,11 @@ class EntityViewsData implements EntityHandlerInterface, EntityViewsDataInterfac
   protected $fieldStorageDefinitions;
 
   /**
+   * @var \Drupal\Core\Entity\EntityManagerInterface
+   */
+  protected $entityManager;
+
+  /**
    * Constructs an EntityViewsData object.
    *
    * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
@@ -112,6 +117,7 @@ public function getViewsData() {
     $data = [];
 
     $base_table = $this->entityType->getBaseTable() ?: $this->entityType->id();
+    $views_revision_base_table = NULL;
     $revisionable = $this->entityType->isRevisionable();
     $base_field = $this->entityType->getKey('id');
 
@@ -235,11 +241,21 @@ public function getViewsData() {
     // Load all typed data definitions of all fields. This should cover each of
     // the entity base, revision, data tables.
     $field_definitions = $this->entityManager->getBaseFieldDefinitions($this->entityType->id());
+    /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
     if ($table_mapping = $this->storage->getTableMapping($field_definitions)) {
       // Fetch all fields that can appear in both the base table and the data
       // table.
       $entity_keys = $this->entityType->getKeys();
       $duplicate_fields = array_intersect_key($entity_keys, array_flip(['id', 'revision', 'bundle']));
+      // Make note of some information so that table joins can be applied for
+      // base fields that have dedicated tables.
+      $dedicated_data_tables = [];
+      foreach ($field_definitions as $field_name => $field_definition) {
+        $storage_definition = $field_definition->getFieldStorageDefinition();
+        if ($revisionable && $storage_definition->isMultiple()) {
+          $dedicated_data_tables[] = $table_mapping->getFieldTableName($field_name);
+        }
+      }
       // Iterate over each table we have so far and collect field data for each.
       // Based on whether the field is in the field_definitions provided by the
       // entity manager.
@@ -257,6 +273,39 @@ public function getViewsData() {
           $this->mapFieldDefinition($table, $field_name, $field_definitions[$field_name], $table_mapping, $data[$table]);
         }
       }
+
+      foreach ($field_definitions as $field_definition) {
+        if ($table_mapping->requiresDedicatedTableStorage($field_definition->getFieldStorageDefinition())) {
+          $table = $table_mapping->getDedicatedDataTableName($field_definition->getFieldStorageDefinition());
+  
+          $data[$table]['table']['group'] = $this->entityType->getLabel();
+          // : $this->t('@entity_type revision', ['@entity_type' => $this->entityType->getLabel()]);
+          $data[$table]['table']['provider'] = $this->entityType->getProvider();
+          //$data[$table]['table']['join'][$is_revision ? $views_revision_base_table : $views_base_table] = [
+          $data[$table]['table']['join'][$views_base_table] = [
+            'left_field' => $base_field,
+            // 'left_field' => $is_revision ? $revision_field : $base_field,
+            'field' => 'entity_id',
+            'extra' => [
+              ['field' => 'deleted', 'value' => 0, 'numeric' => TRUE],
+            ],
+          ];
+
+          if ($revisionable) {
+            $revision_table = $table_mapping->getDedicatedRevisionTableName($field_definition->getFieldStorageDefinition());
+
+            $data[$revision_table]['table']['group'] = $this->t('@entity_type revision', ['@entity_type' => $this->entityType->getLabel()]);
+            $data[$revision_table]['table']['provider'] = $this->entityType->getProvider();
+            $data[$revision_table]['table']['join'][$views_revision_base_table] = [
+              'left_field' => $revision_field,
+              'field' => 'entity_id',
+              'extra' => [
+                ['field' => 'deleted', 'value' => 0, 'numeric' => TRUE],
+              ],
+            ];
+          }
+        }
+      }
     }
 
     // Add the entity type key to each table generated.
diff --git a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
index c3e93ed..05a9098 100644
--- a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
+++ b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
@@ -11,6 +11,7 @@
 use Drupal\Core\Entity\ContentEntityType;
 use Drupal\Core\Entity\EntityType;
 use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Entity\Sql\DefaultTableMapping;
 use Drupal\Core\Field\BaseFieldDefinition;
 use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
 use Drupal\Core\Field\Plugin\Field\FieldType\IntegerItem;
@@ -161,6 +162,12 @@ protected function setupBaseFields(array $base_fields) {
       ->setTranslatable(TRUE)
       ->setSetting('max_length', 255);
 
+    // A base field with cardinality > 1
+    $base_fields['string']  = BaseFieldDefinition::create('string')
+      ->setLabel('Strong')
+      ->setTranslatable(TRUE)
+      ->setCardinality(2);
+
     foreach ($base_fields as $name => $base_field) {
       $base_field->setName($name);
     }
@@ -377,6 +384,10 @@ protected function setupFieldStorageDefinition() {
     $homepage_field_storage_definition->expects($this->any())
       ->method('getSchema')
       ->willReturn(UriItem::schema($homepage_field_storage_definition));
+    $string_field_storage_definition = $this->getMock('Drupal\Core\Field\FieldStorageDefinitionInterface');
+    $string_field_storage_definition->expects($this->any())
+      ->method('getSchema')
+      ->willReturn(StringItem::schema($string_field_storage_definition));
 
     // Setup the user_id entity reference field.
     $this->entityManager->expects($this->any())
@@ -412,6 +423,7 @@ protected function setupFieldStorageDefinition() {
         'name' => $name_field_storage_definition,
         'description' => $description_field_storage_definition,
         'homepage' => $homepage_field_storage_definition,
+        'string' => $string_field_storage_definition,
         'user_id' => $user_id_field_storage_definition,
         'revision_id' => $revision_id_field_storage_definition,
       ]);
@@ -436,10 +448,12 @@ public function testBaseTableFields() {
         ['entity_test', $base_field_definitions],
       ]));
     // Setup the table mapping.
-    $table_mapping = $this->getMock('Drupal\Core\Entity\Sql\TableMappingInterface');
+    $table_mapping = $this->getMockBuilder(DefaultTableMapping::class)
+      ->disableOriginalConstructor()
+      ->getMock();
     $table_mapping->expects($this->any())
       ->method('getTableNames')
-      ->willReturn(['entity_test']);
+      ->willReturn(['entity_test', 'entity_test__string']);
     $table_mapping->expects($this->any())
       ->method('getColumnNames')
       ->willReturnMap([
@@ -451,12 +465,26 @@ public function testBaseTableFields() {
         ['description', ['value' => 'description__value', 'format' => 'description__format']],
         ['homepage', ['value' => 'homepage']],
         ['user_id', ['target_id' => 'user_id']],
+        ['string', ['value' => 'value']],
       ]);
     $table_mapping->expects($this->any())
       ->method('getFieldNames')
       ->willReturnMap([
-        ['entity_test', ['id', 'uuid', 'type', 'langcode', 'name', 'description', 'homepage', 'user_id']]
+        ['entity_test', ['id', 'uuid', 'type', 'langcode', 'name', 'description', 'homepage', 'user_id']],
+        ['entity_test__string', ['string']],
       ]);
+    $table_mapping->expects($this->any())
+      ->method('requiresDedicatedTableStorage')
+      ->willReturnCallback(function (BaseFieldDefinition $base_field) {
+        return $base_field->getName() === 'string';
+      });
+    $table_mapping->expects($this->any())
+      ->method('getDedicatedDataTableName')
+      ->willReturnCallback(function (BaseFieldDefinition $base_field) {
+        if ($base_field->getName() === 'string') {
+          return 'entity_test__string';
+        }
+      });
 
     $this->entityStorage->expects($this->once())
       ->method('getTableMapping')
@@ -493,6 +521,18 @@ public function testBaseTableFields() {
     $relationship = $data['entity_test']['user_id']['relationship'];
     $this->assertEquals('users_field_data', $relationship['base']);
     $this->assertEquals('uid', $relationship['base field']);
+
+    $this->assertStringField($data['entity_test__string']['string']);
+    $this->assertField($data['entity_test__string']['string'], 'string');
+    $this->assertEquals([
+      'left_field' => 'id',
+      'field' => 'entity_id',
+      'extra' => [[
+        'field' => 'deleted',
+        'value' => 0,
+        'numeric' => TRUE,
+      ]],
+    ], $data['entity_test__string']['table']['join']['entity_test']);
   }
 
   /**
@@ -530,10 +570,12 @@ public function testDataTableFields() {
     $this->viewsData->setEntityType($entity_type);
 
      // Setup the table mapping.
-    $table_mapping = $this->getMock('Drupal\Core\Entity\Sql\TableMappingInterface');
+    $table_mapping = $this->getMockBuilder(DefaultTableMapping::class)
+      ->disableOriginalConstructor()
+      ->getMock();
     $table_mapping->expects($this->any())
       ->method('getTableNames')
-      ->willReturn(['entity_test_mul', 'entity_test_mul_property_data']);
+      ->willReturn(['entity_test_mul', 'entity_test_mul_property_data', 'entity_test_mul__string']);
     $table_mapping->expects($this->any())
       ->method('getColumnNames')
       ->willReturnMap([
@@ -545,12 +587,14 @@ public function testDataTableFields() {
         ['description', ['value' => 'description__value', 'format' => 'description__format']],
         ['homepage', ['value' => 'homepage']],
         ['user_id', ['target_id' => 'user_id']],
+        ['string', ['value' => 'value']],
       ]);
     $table_mapping->expects($this->any())
       ->method('getFieldNames')
       ->willReturnMap([
         ['entity_test_mul', ['uuid']],
         ['entity_test_mul_property_data', ['id', 'type', 'langcode', 'name', 'description', 'homepage', 'user_id']],
+        ['entity_test_mul__string', ['string']],
       ]);
 
     $table_mapping->expects($this->any())
@@ -561,6 +605,18 @@ public function testDataTableFields() {
         }
         return 'entity_test_mul_property_data';
       });
+    $table_mapping->expects($this->any())
+      ->method('requiresDedicatedTableStorage')
+      ->willReturnCallback(function (BaseFieldDefinition $base_field) {
+        return $base_field->getName() === 'string';
+      });
+    $table_mapping->expects($this->any())
+      ->method('getDedicatedDataTableName')
+      ->willReturnCallback(function (BaseFieldDefinition $base_field) {
+        if ($base_field->getName() === 'string') {
+          return 'entity_test_mul__string';
+        }
+      });
 
     $this->entityStorage->expects($this->once())
       ->method('getTableMapping')
@@ -620,6 +676,18 @@ public function testDataTableFields() {
     $relationship = $data['entity_test_mul_property_data']['user_id']['relationship'];
     $this->assertEquals('users_field_data', $relationship['base']);
     $this->assertEquals('uid', $relationship['base field']);
+
+    $this->assertStringField($data['entity_test_mul__string']['string']);
+    $this->assertField($data['entity_test_mul__string']['string'], 'string');
+    $this->assertEquals([
+      'left_field' => 'id',
+      'field' => 'entity_id',
+      'extra' => [[
+        'field' => 'deleted',
+        'value' => 0,
+        'numeric' => TRUE,
+      ]],
+    ], $data['entity_test_mul__string']['table']['join']['entity_test_mul']);
   }
 
   /**
@@ -651,10 +719,12 @@ public function testRevisionTableFields() {
     $this->viewsData->setEntityType($entity_type);
 
      // Setup the table mapping.
-    $table_mapping = $this->getMock('Drupal\Core\Entity\Sql\TableMappingInterface');
+    $table_mapping = $this->getMockBuilder(DefaultTableMapping::class)
+      ->disableOriginalConstructor()
+      ->getMock();
     $table_mapping->expects($this->any())
       ->method('getTableNames')
-      ->willReturn(['entity_test_mulrev', 'entity_test_mulrev_revision', 'entity_test_mulrev_property_data', 'entity_test_mulrev_property_revision']);
+      ->willReturn(['entity_test_mulrev', 'entity_test_mulrev_revision', 'entity_test_mulrev_property_data', 'entity_test_mulrev_property_revision', 'entity_test_mulrev__string', 'entity_test_mulrev_revision__string']);
     $table_mapping->expects($this->any())
       ->method('getColumnNames')
       ->willReturnMap([
@@ -667,6 +737,7 @@ public function testRevisionTableFields() {
         ['homepage', ['value' => 'homepage']],
         ['user_id', ['target_id' => 'user_id']],
         ['revision_id', ['value' => 'id']],
+        ['string', ['value' => 'value']],
       ]);
     $table_mapping->expects($this->any())
       ->method('getFieldNames')
@@ -675,7 +746,29 @@ public function testRevisionTableFields() {
         ['entity_test_mulrev_revision', ['id', 'revision_id', 'langcode']],
         ['entity_test_mulrev_property_data', ['id', 'revision_id', 'langcode', 'name', 'description', 'homepage', 'user_id']],
         ['entity_test_mulrev_property_revision', ['id', 'revision_id', 'langcode', 'name', 'description', 'homepage', 'user_id']],
+        ['entity_test_mulrev__string', ['string']],
+        ['entity_test_mulrev_revision__string', ['string']],
       ]);
+    $table_mapping->expects($this->any())
+      ->method('requiresDedicatedTableStorage')
+      ->willReturnCallback(function (BaseFieldDefinition $base_field) {
+        return $base_field->getName() === 'string';
+      });
+    $table_mapping->expects($this->any())
+      ->method('getDedicatedDataTableName')
+      ->willReturnCallback(function (BaseFieldDefinition $base_field) {
+        if ($base_field->getName() === 'string') {
+          return 'entity_test_mulrev__string';
+        }
+      });
+    
+    $table_mapping->expects($this->any())
+      ->method('getDedicatedRevisionTableName')
+      ->willReturnCallback(function (BaseFieldDefinition $base_field) {
+        if ($base_field->getName() === 'string') {
+          return 'entity_test_mulrev_revision__string';
+        }
+      });
 
     $table_mapping->expects($this->any())
       ->method('getFieldTableName')
@@ -768,6 +861,30 @@ public function testRevisionTableFields() {
     $relationship = $data['entity_test_mulrev_property_revision']['user_id']['relationship'];
     $this->assertEquals('users_field_data', $relationship['base']);
     $this->assertEquals('uid', $relationship['base field']);
+
+    $this->assertStringField($data['entity_test_mulrev__string']['string']);
+    $this->assertField($data['entity_test_mulrev__string']['string'], 'string');
+    $this->assertEquals([
+      'left_field' => 'id',
+      'field' => 'entity_id',
+      'extra' => [[
+        'field' => 'deleted',
+        'value' => 0,
+        'numeric' => TRUE,
+      ]],
+    ], $data['entity_test_mulrev__string']['table']['join']['entity_test_mulrev_property_data']);
+
+    $this->assertStringField($data['entity_test_mulrev_revision__string']['string']);
+    $this->assertField($data['entity_test_mulrev_revision__string']['string'], 'string');
+    $this->assertEquals([
+      'left_field' => 'revision_id',
+      'field' => 'entity_id',
+      'extra' => [[
+        'field' => 'deleted',
+        'value' => 0,
+        'numeric' => TRUE,
+      ]],
+    ], $data['entity_test_mulrev_revision__string']['table']['join']['entity_test_mulrev_property_revision']);
   }
 
   /**
