diff --git a/core/modules/views/src/EntityViewsData.php b/core/modules/views/src/EntityViewsData.php
index 61def5acd4..51a25ec9af 100644
--- a/core/modules/views/src/EntityViewsData.php
+++ b/core/modules/views/src/EntityViewsData.php
@@ -366,19 +366,15 @@ protected function mapFieldDefinition($table, $field_name, FieldDefinitionInterf
     $field_schema = $this->getFieldStorageDefinitions()[$field_name]->getSchema();
 
     $field_definition_type = $field_definition->getType();
-    // Add all properties to views table data. We need an entry for each
-    // column of each field, with the first one given special treatment.
-    // @todo Introduce concept of the "main" column for a field, rather than
-    //   assuming the first one is the main column. See also what the
-    //   mapSingleFieldViewsData() method does with $first.
     $multiple = (count($field_column_mapping) > 1);
-    $first = TRUE;
+    $main_property = $this->getFieldStorageDefinitions()[$field_name]->getMainPropertyName();
+    // Add an entry for each column of each field into views table data.
     foreach ($field_column_mapping as $field_column_name => $schema_field_name) {
       $views_field_name = ($multiple) ? $field_name . '__' . $field_column_name : $field_name;
-      $table_data[$views_field_name] = $this->mapSingleFieldViewsData($table, $field_name, $field_definition_type, $field_column_name, $field_schema['columns'][$field_column_name]['type'], $first, $field_definition);
-
+      $column_type = $field_schema['columns'][$field_column_name]['type'];
+      $is_main_property = $field_column_name === $main_property;
+      $table_data[$views_field_name] = $this->mapSingleFieldViewsData($table, $field_name, $field_definition_type, $field_column_name, $column_type, $is_main_property, $field_definition);
       $table_data[$views_field_name]['entity field'] = $field_name;
-      $first = FALSE;
     }
   }
 
@@ -395,21 +391,19 @@ protected function mapFieldDefinition($table, $field_name, FieldDefinitionInterf
    *   For fields containing multiple columns, the column name being processed.
    * @param string $column_type
    *   Within the field, the column type being handled.
-   * @param bool $first
-   *   TRUE if this is the first column within the field.
+   * @param bool $is_main_property
+   *   TRUE if this is the main property/column of the field.
    * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
    *   The field definition.
    *
    * @return array
    *   The modified views data field definition.
    */
-  protected function mapSingleFieldViewsData($table, $field_name, $field_type, $column_name, $column_type, $first, FieldDefinitionInterface $field_definition) {
+  protected function mapSingleFieldViewsData($table, $field_name, $field_type, $column_name, $column_type, $is_main_property, FieldDefinitionInterface $field_definition) {
     $views_field = array();
 
-    // Provide a nicer, less verbose label for the first column within a field.
-    // @todo Introduce concept of the "main" column for a field, rather than
-    //   assuming the first one is the main column.
-    if ($first) {
+    // Provide a nicer, less verbose label for field's main property.
+    if ($is_main_property) {
       $views_field['title'] = $field_definition->getLabel();
     }
     else {
diff --git a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
index acb84e5f1e..4df13508f9 100644
--- a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
+++ b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
@@ -129,6 +129,7 @@ protected function setUp() {
     $container->set('plugin.manager.field.field_type', $field_type_manager);
     $container->set('entity.manager', $this->entityManager);
     $container->set('typed_data_manager', $typed_data_manager);
+    $container->set('string_translation', $this->translationManager);
     \Drupal::setContainer($container);
   }
 
@@ -385,6 +386,9 @@ protected function setupFieldStorageDefinition() {
     $description_field_storage_definition->expects($this->any())
       ->method('getSchema')
       ->willReturn(TextLongItem::schema($description_field_storage_definition));
+    $description_field_storage_definition->expects($this->any())
+      ->method('getMainPropertyName')
+      ->willReturn(TextLongItem::mainPropertyName());
     $homepage_field_storage_definition = $this->getMock('Drupal\Core\Field\FieldStorageDefinitionInterface');
     $homepage_field_storage_definition->expects($this->any())
       ->method('getSchema')
@@ -467,7 +471,7 @@ public function testBaseTableFields() {
         ['type', ['value' => 'type']],
         ['langcode', ['value' => 'langcode']],
         ['name', ['value' => 'name']],
-        ['description', ['value' => 'description__value', 'format' => 'description__format']],
+        ['description', ['format' => 'description__format', 'value' => 'description__value']],
         ['homepage', ['value' => 'homepage']],
         ['user_id', ['target_id' => 'user_id']],
         ['string', ['value' => 'value']],
@@ -516,6 +520,10 @@ public function testBaseTableFields() {
     $this->assertLongTextField($data['entity_test'], 'description');
     $this->assertField($data['entity_test']['description__value'], 'description');
     $this->assertField($data['entity_test']['description__format'], 'description');
+    // Check that the main property title has no ' (<property>)' suffix.
+    $this->assertStringEndsNotWith(' (value)', $data['entity_test']['description__value']['title']);
+    // Check that the minor property titles have the ' (<property>)' suffix.
+    $this->assertStringEndsWith(' (format)', $data['entity_test']['description__format']['title']);
 
     $this->assertUriField($data['entity_test']['homepage']);
     $this->assertField($data['entity_test']['homepage'], 'homepage');
