diff --git a/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
index b5fccbd..3e12f7e 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityBase.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
@@ -503,6 +503,51 @@ protected function getTranslatedField($name, $langcode) {
   }
 
   /**
+   * Gets the value of a specific property of a field.
+   *
+   * Only the first delta can be accessed with this method.
+   *
+   * @param string $field_name
+   *   The name of the field.
+   * @param string $property
+   *   The field property, "value" for many field types.
+   *
+   * @return mixed
+   */
+  public function getFieldValue($field_name, $property) {
+    // Attempt to get the value from the values directly if the field is not
+    // initialized yet.
+    if (!isset($this->fields[$field_name])) {
+      $field_values = NULL;
+      if (isset($this->values[$field_name][$this->activeLangcode])) {
+        $field_values = $this->values[$field_name][$this->activeLangcode];
+      }
+      elseif ($this->values[$field_name][LanguageInterface::LANGCODE_DEFAULT]) {
+        $field_values = $this->values[$field_name][LanguageInterface::LANGCODE_DEFAULT];
+      }
+
+      if ($field_values !== NULL) {
+        // If there are field values, try to get the property value.
+        // Configurable/Multi-value fields are stored differently, try accessing
+        // with delta and property first, then without delta and last, if the
+        // value are a scalar, just return that.
+        if (isset($field_values[0][$property]) && is_array($field_values[0])) {
+          return $field_values[0][$property];
+        }
+        elseif (isset($field_values[$property]) && is_array($field_values)) {
+          return $field_values[$property];
+        }
+        elseif (!is_array($field_values)) {
+          return $field_values;
+        }
+      }
+    }
+
+    // Fall back to access the property through the field object.
+    return $this->get($field_name)->$property;
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function set($name, $value, $notify = TRUE) {
diff --git a/core/modules/comment/src/CommentLazyBuilders.php b/core/modules/comment/src/CommentLazyBuilders.php
index 4eeeb59..d1d5f5b 100644
--- a/core/modules/comment/src/CommentLazyBuilders.php
+++ b/core/modules/comment/src/CommentLazyBuilders.php
@@ -163,7 +163,7 @@ public function renderLinks($comment_entity_id, $view_mode, $langcode, $is_in_pr
    */
   protected function buildLinks(CommentInterface $entity, EntityInterface $commented_entity) {
     $links = array();
-    $status = $commented_entity->get($entity->getFieldName())->status;
+    $status = $commented_entity->getFieldValue($entity->getFieldName(), 'status');
 
     if ($status == CommentItemInterface::OPEN) {
       if ($entity->access('delete')) {
diff --git a/core/modules/comment/src/Entity/Comment.php b/core/modules/comment/src/Entity/Comment.php
index 0f34925..caf2a9b 100644
--- a/core/modules/comment/src/Entity/Comment.php
+++ b/core/modules/comment/src/Entity/Comment.php
@@ -356,21 +356,25 @@ public function getParentComment() {
    * {@inheritdoc}
    */
   public function getCommentedEntity() {
-    return $this->get('entity_id')->entity;
+    if ($this->getCommentedEntityTypeId() && $entity_id = $this->getCommentedEntityId()) {
+      return $this->entityTypeManager()
+        ->getStorage($this->getCommentedEntityTypeId())
+        ->load($entity_id);
+    }
   }
 
   /**
    * {@inheritdoc}
    */
   public function getCommentedEntityId() {
-    return $this->get('entity_id')->target_id;
+    return $this->getFieldValue('entity_id', 'target_id');
   }
 
   /**
    * {@inheritdoc}
    */
   public function getCommentedEntityTypeId() {
-    return $this->get('entity_type')->value;
+    return $this->getFieldValue('entity_type', 'value');
   }
 
   /**
@@ -385,7 +389,7 @@ public function setFieldName($field_name) {
    * {@inheritdoc}
    */
   public function getFieldName() {
-    return $this->get('field_name')->value;
+    return $this->getFieldValue('field_name', 'value');
   }
 
   /**
@@ -486,14 +490,14 @@ public function setCreatedTime($created) {
    * {@inheritdoc}
    */
   public function isPublished() {
-    return $this->get('status')->value == CommentInterface::PUBLISHED;
+    return $this->getFieldValue('status', 'value') == CommentInterface::PUBLISHED;
   }
 
   /**
    * {@inheritdoc}
    */
   public function getStatus() {
-    return $this->get('status')->value;
+    return $this->getFieldValue('status', 'value');
   }
 
   /**
@@ -549,7 +553,7 @@ public function getOwner() {
    * {@inheritdoc}
    */
   public function getOwnerId() {
-    return $this->get('uid')->target_id;
+    return $this->getFieldValue('uid', 'target_id');
   }
 
   /**
diff --git a/core/modules/user/src/Authentication/Provider/Cookie.php b/core/modules/user/src/Authentication/Provider/Cookie.php
index 2f8624e..37051b8 100644
--- a/core/modules/user/src/Authentication/Provider/Cookie.php
+++ b/core/modules/user/src/Authentication/Provider/Cookie.php
@@ -3,12 +3,9 @@
 namespace Drupal\user\Authentication\Provider;
 
 use Drupal\Core\Authentication\AuthenticationProviderInterface;
-use Drupal\Core\Database\Connection;
-use Drupal\Core\Session\AccountInterface;
-use Drupal\Core\Session\UserSession;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Session\SessionConfigurationInterface;
 use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\HttpFoundation\Session\SessionInterface;
 
 /**
  * Cookie based authentication provider.
@@ -23,23 +20,23 @@ class Cookie implements AuthenticationProviderInterface {
   protected $sessionConfiguration;
 
   /**
-   * The database connection.
+   * The entity type manager.
    *
-   * @var \Drupal\Core\Database\Connection
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
    */
-  protected $connection;
+  protected $entityTypeManager;
 
   /**
    * Constructs a new cookie authentication provider.
    *
    * @param \Drupal\Core\Session\SessionConfigurationInterface $session_configuration
    *   The session configuration.
-   * @param \Drupal\Core\Database\Connection $connection
-   *   The database connection.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
    */
-  public function __construct(SessionConfigurationInterface $session_configuration, Connection $connection) {
+  public function __construct(SessionConfigurationInterface $session_configuration, EntityTypeManagerInterface $entity_type_manager) {
     $this->sessionConfiguration = $session_configuration;
-    $this->connection = $connection;
+    $this->entityTypeManager = $entity_type_manager;
   }
 
   /**
@@ -53,41 +50,14 @@ public function applies(Request $request) {
    * {@inheritdoc}
    */
   public function authenticate(Request $request) {
-    return $this->getUserFromSession($request->getSession());
-  }
-
-  /**
-   * Returns the UserSession object for the given session.
-   *
-   * @param \Symfony\Component\HttpFoundation\Session\SessionInterface $session
-   *   The session.
-   *
-   * @return \Drupal\Core\Session\AccountInterface|NULL
-   *   The UserSession object for the current user, or NULL if this is an
-   *   anonymous session.
-   */
-  protected function getUserFromSession(SessionInterface $session) {
-    if ($uid = $session->get('uid')) {
-      // @todo Load the User entity in SessionHandler so we don't need queries.
-      // @see https://www.drupal.org/node/2345611
-      $values = $this->connection
-        ->query('SELECT * FROM {users_field_data} u WHERE u.uid = :uid AND u.default_langcode = 1', [':uid' => $uid])
-        ->fetchAssoc();
-
-      // Check if the user data was found and the user is active.
-      if (!empty($values) && $values['status'] == 1) {
-        // Add the user's roles.
-        $rids = $this->connection
-          ->query('SELECT roles_target_id FROM {user__roles} WHERE entity_id = :uid', [':uid' => $values['uid']])
-          ->fetchCol();
-        $values['roles'] = array_merge([AccountInterface::AUTHENTICATED_ROLE], $rids);
-
-        return new UserSession($values);
+    if ($uid = $request->getSession()->get('uid')) {
+      /** @var \Drupal\user\UserInterface $user */
+      if ($user = $this->entityTypeManager->getStorage('user')->load($uid)) {
+        if ($user->isActive()) {
+          return $user;
+        }
       }
     }
-
-    // This is an anonymous session.
-    return NULL;
   }
 
 }
diff --git a/core/modules/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php
index 4896bad..5dd31be 100644
--- a/core/modules/user/src/Entity/User.php
+++ b/core/modules/user/src/Entity/User.php
@@ -152,9 +152,22 @@ public function getRoles($exclude_locked_roles = FALSE) {
       }
     }
 
-    foreach ($this->get('roles') as $role) {
-      if ($role->target_id) {
-        $roles[] = $role->target_id;
+    // Optimize for the case where the field object has not been initialized
+    // yet, directly access the values.
+    if (!isset($this->fields['roles'])) {
+      if (isset($this->values['roles'][LanguageInterface::LANGCODE_DEFAULT][0])) {
+        foreach ($this->values['roles'][LanguageInterface::LANGCODE_DEFAULT] as $values) {
+          if (isset($values['target_id'])) {
+            $roles[] = $values['target_id'];
+          }
+        }
+      }
+    }
+    else {
+      foreach ($this->get('roles') as $role) {
+        if ($role->target_id) {
+          $roles[] = $role->target_id;
+        }
       }
     }
 
@@ -242,7 +255,7 @@ public function getCreatedTime() {
    * {@inheritdoc}
    */
   public function getLastAccessedTime() {
-    return $this->get('access')->value;
+    return $this->getFieldValue('access', 'value');
   }
 
   /**
@@ -272,14 +285,14 @@ public function setLastLoginTime($timestamp) {
    * {@inheritdoc}
    */
   public function isActive() {
-    return $this->get('status')->value == 1;
+    return $this->getFieldValue('status', 'value') == 1;
   }
 
   /**
    * {@inheritdoc}
    */
   public function isBlocked() {
-    return $this->get('status')->value == 0;
+    return $this->getFieldValue('status', 'value') == 0;
   }
 
   /**
@@ -302,7 +315,7 @@ public function block() {
    * {@inheritdoc}
    */
   public function getTimeZone() {
-    return $this->get('timezone')->value;
+    return $this->getFieldValue('timezone', 'value');
   }
 
   /**
@@ -364,7 +377,7 @@ public function getUsername() {
    * {@inheritdoc}
    */
   public function getAccountName() {
-    return $this->get('name')->value ?: '';
+    return $this->getFieldValue('name', 'value') ?: '';
   }
 
   /**
diff --git a/core/modules/user/tests/src/Unit/Plugin/Core/Entity/UserTest.php b/core/modules/user/tests/src/Unit/Plugin/Core/Entity/UserTest.php
index f3a5424..3a7fd25 100644
--- a/core/modules/user/tests/src/Unit/Plugin/Core/Entity/UserTest.php
+++ b/core/modules/user/tests/src/Unit/Plugin/Core/Entity/UserTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\user\Unit\Plugin\Core\Entity;
 
+use Drupal\Core\Language\LanguageInterface;
 use Drupal\Tests\Core\Session\UserSessionTest;
 use Drupal\user\RoleInterface;
 
@@ -15,24 +16,28 @@ class UserTest extends UserSessionTest {
    * {@inheritdoc}
    */
   protected function createUserSession(array $rids = array(), $authenticated = FALSE) {
+    $roles = array();
+    foreach ($rids as $rid) {
+      $roles[] = array(
+        'target_id' => $rid,
+      );
+    }
+    $values = ['roles' => [LanguageInterface::LANGCODE_DEFAULT => $roles]];
+
     $user = $this->getMockBuilder('Drupal\user\Entity\User')
       ->disableOriginalConstructor()
-      ->setMethods(array('get', 'id'))
+      ->setMethods(array('id'))
       ->getMock();
+
+    $reflect = new \ReflectionObject($user);
+    $property = $reflect->getProperty('values');
+    $property->setAccessible(TRUE);
+    $property->setValue($user, $values);
+
     $user->expects($this->any())
       ->method('id')
       // @todo Also test the uid = 1 handling.
       ->will($this->returnValue($authenticated ? 2 : 0));
-    $roles = array();
-    foreach ($rids as $rid) {
-      $roles[] = (object) array(
-        'target_id' => $rid,
-      );
-    }
-    $user->expects($this->any())
-      ->method('get')
-      ->with('roles')
-      ->will($this->returnValue($roles));
     return $user;
   }
 
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 0e9cedb..dcb9f29 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -761,6 +761,7 @@ function _user_cancel($edit, $account, $method) {
   // regenerate it because batch API uses the session ID, we will regenerate it
   // in _user_cancel_session_regenerate().
   if ($account->id() == \Drupal::currentUser()->id()) {
+    \Drupal::request()->getSession()->remove('uid');
     \Drupal::currentUser()->setAccount(new AnonymousUserSession());
   }
 }
diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml
index 8fc9bf5..315cb6e 100644
--- a/core/modules/user/user.services.yml
+++ b/core/modules/user/user.services.yml
@@ -17,7 +17,7 @@ services:
       - { name: access_check, applies_to: _user_is_logged_in }
   user.authentication.cookie:
     class: Drupal\user\Authentication\Provider\Cookie
-    arguments: ['@session_configuration', '@database']
+    arguments: ['@session_configuration', '@entity_type.manager']
     tags:
       - { name: authentication_provider, provider_id: 'cookie', priority: 0, global: TRUE }
   user.data:
