It is possible to create a reusable pagination. What we need is:
- partial view to store number of pages and links to them
 
- reusable methods which contains pagination logic for 
IQueryable 
The complete example with source code can be seen here.
So our code would like this:
The person table. I've used SQL Server:
IF NOT EXISTS 
(
    SELECT 1
    FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Person'
    AND TABLE_SCHEMA = 'dbo'
)
BEGIN
    CREATE TABLE dbo.Person 
    (
          ID                 INT                 IDENTITY(1, 1) NOT NULL PRIMARY KEY
        , CreateDate         DATETIME            NOT NULL DEFAULT GETDATE()
        , Creator            VARCHAR(100)        NOT NULL
        , ModifyDate         DATETIME            NULL
        , Modifier           VARCHAR(20)         NULL
        , FirstName          VARCHAR(150)        NOT NULL
        , LastName           VARCHAR(1000)       NOT NULL        
    )
ON [PRIMARY]
END
GO
I've used DatabaseFirst approach. This is a generated class by Entity Framework.
public partial class Person
{
    public int ID { get; set; }
    public System.DateTime CreateDate { get; set; }
    public string Creator { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Nullable<System.DateTime> ModifyDate { get; set; }
    public string Modifier { get; set; }
}
This is a class which contains data and pagination information:
public class DataResultViewModel<T>
{
    /// <summary>
    /// Data items
    /// </summary>
    public IEnumerable<T> Items { get; set; }
    /// <summary>
    /// Pagination
    /// </summary>
    public Pagination Pagination { get; set; }
}
This is class which contains information about persons.
public class PersonViewModel
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
/// <summary>
/// What route should be requested while paging
/// </summary>
public class RouteInfo
{
    /// <summary>
    /// Name of controller
    /// </summary>
    public string ControllerName { get; set; }
    /// <summary>
    /// Name of action
    /// </summary>
    public string ActionName { get; set; }
}
and Pagination class:
public class Pagination
{
    /// <summary>
    /// Total count of items
    /// </summary>
    public int TotalItems { get; set; }
    /// <summary>
    /// Count of items at the page
    /// </summary>
    public int PageSize { get; set; } = 5;
    /// <summary>
    /// Current page
    /// </summary>
    public int Page { get; set; }
    /// <summary>
    /// Sorted by field name
    /// </summary>
    public string SortBy { get; set; }
    /// <summary>
    /// Is this an ascending sort?
    /// </summary>
    public bool IsSortAscending { get; set; }
    /// <summary>
    /// Information about what page should be requested
    /// </summary>
    public RouteInfo RouteInfo { get; set; }
}
And the class which makes pagination. Basically, Skip() and Take() are methods which do a pagination, so we need to use these methods for all IQueryable. And C# has a very neat feature called extension methods. Extension methods allow to reuse code:
public static class IQueryableExtension
{
    public static IQueryable<T> UseOrdering<T, TResultSelector>(this IQueryable<T> query, 
        Pagination pagination,
             Expression<Func<T, TResultSelector>> field)
    {
        if (string.IsNullOrWhiteSpace(pagination.SortBy) 
            || string.IsNullOrEmpty(pagination.SortBy))
            return query;
        return pagination.IsSortAscending ?
            query.OrderBy(field) :
            query.OrderByDescending(field);
    }
    public static IQueryable<T> UsePagination<T>(this IQueryable<T> query, 
        Pagination pagination)
    {
        if (pagination.Page <= 0)
            pagination.Page = 1;
        if (pagination.PageSize <= 0)
            pagination.PageSize = 10;
         return query.Skip((pagination.Page - 1) * pagination.PageSize)
             .Take(pagination.PageSize);
    }
}
This is a class of service layer:
public class PersonService
{
    public DataResultViewModel<PersonViewModel> GetWithPagination(Pagination pagination,
        Expression<Func<Person, DateTime>> fieldName)
    {
        var result = new DataResultViewModel<PersonViewModel>();
        using (var db = new MiscellaneousEntities())
        {
            var persons = db.Person.AsQueryable();
            result.Pagination = pagination;
            result.Pagination.TotalItems = persons.Count();
            result.Pagination.RouteInfo = new RouteInfo() 
            {
                ActionName = "Index", 
                ControllerName = "Person"
            };
            if (pagination.SortBy == null)
                pagination.SortBy = "CreateDate";
            persons = persons.UseOrdering(pagination, fieldName);
            persons = persons.UsePagination(pagination);
            result.Items = persons
                .Select(s => new PersonViewModel()
                {
                    ID = s.ID,
                    FirstName = s.FirstName,
                    LastName = s.LastName
                })
                .ToList();
             return result;
        }
    }
}
And controller of person:
public class PersonController : Controller
{
    PersonService _personService;
    public PersonController()
    {
        _personService = new PersonService();
    }
    // GET: Person
    public ActionResult Index(int? page, int? pageSize, string sortBy,
        bool? isSortAscending)
    {
        return View
            (_personService.GetWithPagination(new Pagination()
                {
                    Page = page ?? 1,
                    PageSize = pageSize ?? 3,
                    SortBy = sortBy,
                    IsSortAscending = isSortAscending ?? false
                },
                v => v.CreateDate
                )
            );
    }
}
Then we should create views.
This is a person view that should be paginated:
@model  OnlyPagination.ViewModel.DataResultViewModel<OnlyPagination.ViewModel.PersonViewModel>
<div class="d-flex justify-content-center">
    <div>
        @foreach (var item in Model.Items)
        {
            <div>
                <p>Id is @item.ID</p>
                <p>FirstName is @item.FirstName</p>
                <p>LastName is @item.LastName</p>
            </div>
            <hr />
        }
    </div>
</div>
<div class="d-flex justify-content-center">
    @{
        @Html.Partial("Pagination", Model.Pagination)
    }
</div>
And it is a reusable pagination partial view:
@model OnlyPagination.Extensions.Query.Model.Pagination
@{
    var pagesCount = Math.Ceiling((decimal)Model.TotalItems / (decimal)Model.PageSize);
    var pages = new List<int>();
    for (var i = 1; i <= pagesCount; i++)
    {
        pages.Add(i);
    }
}
<div>
    <p class="d-flex justify-content-center">Page @Model.Page of @pagesCount</p>
    <ul class="pagination">
        <li class="page-item @( Model.Page == 1 ? "disabled" : "" )">
            <a aria-label="Previous" class="page-link"
                href="@Url.Action
                (Model.RouteInfo.ActionName, Model.RouteInfo.ControllerName,
                new { page = Model.Page - 1, pageSize = Model.PageSize })">
                <span aria-hidden="true">«</span>
            </a>
        </li>
        @for (int pageNumber = 1; pageNumber <= pages.Count; pageNumber++)
        {
            <li class="page-item @( Model.Page == pageNumber ? "active" : "" )">
                <a class="page-link"
                    href="@Url.Action(Model.RouteInfo.ActionName, 
                        Model.RouteInfo.ControllerName,
                        new { page = pageNumber, pageSize = Model.PageSize })"> 
                        @pageNumber </a>
                </li>
            }
        <li class="page-item @(Model.Page == pages.Count ? "disabled" : "")">
            <a aria-label="Next" class="page-link"
                href="@Url.Action
                      (Model.RouteInfo.ActionName, Model.RouteInfo.ControllerName,
                      new { page = Model.Page + 1, pageSize = Model.PageSize })">
                <span aria-hidden="true">»</span>
            </a>
        </li>
    </ul>
</div>
That's all!