MVC simple Employee table with paging using SP











up vote
2
down vote

favorite












I am a beginner web developer and I have to do an exercise to show an Employee table using a WCF service, 10 entries at a time, with the paging of the table controlled by a stored procedure. What I would like to know is if the code complies with best practices, and how I can improve it?



The service1.svc.cs class:



public class Service1 : IService1
{
private string connection_string = ConfigurationManager.ConnectionStrings["EmployeeDB"].ConnectionString.ToString();

public List<Employee> getEmployees(int startRowIndex, int maximumRows)
{
List<Employee> employees = new List<Employee>();
SqlConnection connection = new SqlConnection(connection_string);

SqlCommand command = new SqlCommand();
command.CommandText = "getEmployees";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("@startRowIndex", startRowIndex));
command.Parameters.Add(new SqlParameter("@maximumRows", maximumRows));

try
{
connection.Open();
SqlDataReader dr = command.ExecuteReader();

while (dr.Read())
{
Employee employee = new Employee();
employee.ID = Convert.ToInt32(dr["EmployeeID"]) == 0 ? 0 : Convert.ToInt32(dr["EmployeeID"]);
employee.Name = dr["Name"].ToString() == string.Empty ? "" : dr["Name"].ToString();
employee.Surname = dr["Surname"].ToString() == string.Empty ? "" : dr["Surname"].ToString();
employee.Address = dr["Address"].ToString() == string.Empty ? "" : dr["Address"].ToString();
employee.Telephone = dr["Telephone"].ToString() == string.Empty ? "" : dr["Telephone"].ToString();
employees.Add(employee);
}
connection.Close();
return employees;
}
catch (Exception e) { throw e; }
}
public int getTotalEmployees()
{
int total = 0;

using (SqlConnection connection = new SqlConnection(connection_string))
{
SqlCommand command = new SqlCommand();
command.CommandText = "getTotalEmployees";
command.CommandType = CommandType.StoredProcedure;
try
{
connection.Open();
total = Convert.ToInt32(command.ExecuteScalar());
}
catch (Exception ex) { throw ex; }
}
return total;
}
}


The service interface:



[ServiceContract]
public interface IService1
{
[OperationContract]
List<Employee> getEmployees(int startRowIndex, int maximumRows);
[OperationContract]
int getTotalEmployees();
}

[DataContract]
public class Employee
{
[DataMember]
public int ID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Surname { get; set; }
[DataMember]
public string Address { get; set; }
[DataMember]
public string Telephone { get; set; }
}


Data Access Layer:



public class DALEmployee
{
EmployeeService.Service1Client client = new EmployeeService.Service1Client();
public List<Employee> getEmployees(int startRowIndex, int maximumRows)
{
List<Employee> employees = new List<Employee>();
var employeeData = client.getEmployees(startRowIndex, maximumRows);
if (employeeData.Count() > 0)
{
foreach (var item in employeeData)
{
Employee employee = new Employee() { ID = item.ID, Address = item.Address, Name = item.Name, Surname = item.Surname, Telephone = item.Telephone };
employees.Add(employee);
}
}
return employees;
}
public int getTotalEmployees()
{
return client.getTotalEmployees();
}
}


Controller:



public class HomeController : Controller
{
private EmployeeService.Service1Client client = new EmployeeService.Service1Client();
int maximumRows = 10;

public ActionResult Index()
{
double startRowIndex = Convert.ToDouble(Session["startRowIndex"]) == 0 ? 1 : Convert.ToDouble(Session["startRowIndex"]);
Session["startRowIndex"] = startRowIndex;
int totalEmployees = new DALEmployee().getTotalEmployees();
ViewBag.PageNumber = Math.Floor(startRowIndex / maximumRows) == 0 ? 1 : Math.Floor(startRowIndex / maximumRows);
List<Employee> employees = new DALEmployee().getEmployees(Convert.ToInt32(startRowIndex), maximumRows);
return View(employees);
}

public ActionResult Next()
{
int startRowIndex = Convert.ToInt32(Session["startRowIndex"]) <= maximumRows ? 1 + maximumRows : Convert.ToInt32(Session["startRowIndex"]) + maximumRows;
Session["startRowIndex"] = startRowIndex;
return RedirectToAction("Index");
}

public ActionResult Previous()
{
int startRowIndex = Convert.ToInt32(Session["startRowIndex"]) <= maximumRows ? 1 : Convert.ToInt32(Session["startRowIndex"]) - maximumRows;
Session["startRowIndex"] = startRowIndex;
return RedirectToAction("Index");
}
}


View:



@model IEnumerable<ExerciseER.Models.Employee>
@{
ViewBag.Title = "Employee Information";
}
<div class="jumbotron">
<table class="table table-bordered">
<thead>
<tr>
<th>@Html.DisplayNameFor(model => model.Name)</th>
<th>@Html.DisplayNameFor(model => model.Surname)</th>
<th>@Html.DisplayNameFor(model => model.Address)</th>
<th>@Html.DisplayNameFor(model => model.Telephone)</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@Html.DisplayFor(model => item.Name)</td>
<td>@Html.DisplayFor(model => item.Surname)</td>
<td>@Html.DisplayFor(model => item.Address)</td>
<td>@Html.DisplayFor(model => item.Telephone)</td>
</tr>
}
<tr>
<td>@Html.ActionLink("Previous", "Previous", null, new { @class = "btn btn-info"})</td>
<td>@ViewBag.PageNumber</td>
<td>@Html.ActionLink("Next", "Next", null, new { @class = "btn btn-info" })</td>
</tr>
</tbody>
</table>
</div>


getEmployees SP with paging:



create procedure getEmployees
(
@startRowIndex int,
@maximumRows int
)
AS

declare @firstInt int, @startRow int
if (@startRowIndex <= (select COUNT(EmployeeID) from dbo.[Employee]))
begin
set ROWCOUNT @startRowIndex

select @firstInt = EmployeeID from dbo.[Employee] order by EmployeeID

set ROWCOUNT @maximumRows

select EmployeeID, Name, Surname, Address, Telephone
from dbo.[Employee] where EmployeeID >= @firstInt order by EmployeeID

set ROWCOUNT 0
end
GO


getTotalEmployees SP:



create procedure getTotalEmployees
as

select COUNT(EmployeeId) from dbo.[Employee] where [Status] = 1

go









share|improve this question




























    up vote
    2
    down vote

    favorite












    I am a beginner web developer and I have to do an exercise to show an Employee table using a WCF service, 10 entries at a time, with the paging of the table controlled by a stored procedure. What I would like to know is if the code complies with best practices, and how I can improve it?



    The service1.svc.cs class:



    public class Service1 : IService1
    {
    private string connection_string = ConfigurationManager.ConnectionStrings["EmployeeDB"].ConnectionString.ToString();

    public List<Employee> getEmployees(int startRowIndex, int maximumRows)
    {
    List<Employee> employees = new List<Employee>();
    SqlConnection connection = new SqlConnection(connection_string);

    SqlCommand command = new SqlCommand();
    command.CommandText = "getEmployees";
    command.CommandType = CommandType.StoredProcedure;
    command.Parameters.Add(new SqlParameter("@startRowIndex", startRowIndex));
    command.Parameters.Add(new SqlParameter("@maximumRows", maximumRows));

    try
    {
    connection.Open();
    SqlDataReader dr = command.ExecuteReader();

    while (dr.Read())
    {
    Employee employee = new Employee();
    employee.ID = Convert.ToInt32(dr["EmployeeID"]) == 0 ? 0 : Convert.ToInt32(dr["EmployeeID"]);
    employee.Name = dr["Name"].ToString() == string.Empty ? "" : dr["Name"].ToString();
    employee.Surname = dr["Surname"].ToString() == string.Empty ? "" : dr["Surname"].ToString();
    employee.Address = dr["Address"].ToString() == string.Empty ? "" : dr["Address"].ToString();
    employee.Telephone = dr["Telephone"].ToString() == string.Empty ? "" : dr["Telephone"].ToString();
    employees.Add(employee);
    }
    connection.Close();
    return employees;
    }
    catch (Exception e) { throw e; }
    }
    public int getTotalEmployees()
    {
    int total = 0;

    using (SqlConnection connection = new SqlConnection(connection_string))
    {
    SqlCommand command = new SqlCommand();
    command.CommandText = "getTotalEmployees";
    command.CommandType = CommandType.StoredProcedure;
    try
    {
    connection.Open();
    total = Convert.ToInt32(command.ExecuteScalar());
    }
    catch (Exception ex) { throw ex; }
    }
    return total;
    }
    }


    The service interface:



    [ServiceContract]
    public interface IService1
    {
    [OperationContract]
    List<Employee> getEmployees(int startRowIndex, int maximumRows);
    [OperationContract]
    int getTotalEmployees();
    }

    [DataContract]
    public class Employee
    {
    [DataMember]
    public int ID { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public string Surname { get; set; }
    [DataMember]
    public string Address { get; set; }
    [DataMember]
    public string Telephone { get; set; }
    }


    Data Access Layer:



    public class DALEmployee
    {
    EmployeeService.Service1Client client = new EmployeeService.Service1Client();
    public List<Employee> getEmployees(int startRowIndex, int maximumRows)
    {
    List<Employee> employees = new List<Employee>();
    var employeeData = client.getEmployees(startRowIndex, maximumRows);
    if (employeeData.Count() > 0)
    {
    foreach (var item in employeeData)
    {
    Employee employee = new Employee() { ID = item.ID, Address = item.Address, Name = item.Name, Surname = item.Surname, Telephone = item.Telephone };
    employees.Add(employee);
    }
    }
    return employees;
    }
    public int getTotalEmployees()
    {
    return client.getTotalEmployees();
    }
    }


    Controller:



    public class HomeController : Controller
    {
    private EmployeeService.Service1Client client = new EmployeeService.Service1Client();
    int maximumRows = 10;

    public ActionResult Index()
    {
    double startRowIndex = Convert.ToDouble(Session["startRowIndex"]) == 0 ? 1 : Convert.ToDouble(Session["startRowIndex"]);
    Session["startRowIndex"] = startRowIndex;
    int totalEmployees = new DALEmployee().getTotalEmployees();
    ViewBag.PageNumber = Math.Floor(startRowIndex / maximumRows) == 0 ? 1 : Math.Floor(startRowIndex / maximumRows);
    List<Employee> employees = new DALEmployee().getEmployees(Convert.ToInt32(startRowIndex), maximumRows);
    return View(employees);
    }

    public ActionResult Next()
    {
    int startRowIndex = Convert.ToInt32(Session["startRowIndex"]) <= maximumRows ? 1 + maximumRows : Convert.ToInt32(Session["startRowIndex"]) + maximumRows;
    Session["startRowIndex"] = startRowIndex;
    return RedirectToAction("Index");
    }

    public ActionResult Previous()
    {
    int startRowIndex = Convert.ToInt32(Session["startRowIndex"]) <= maximumRows ? 1 : Convert.ToInt32(Session["startRowIndex"]) - maximumRows;
    Session["startRowIndex"] = startRowIndex;
    return RedirectToAction("Index");
    }
    }


    View:



    @model IEnumerable<ExerciseER.Models.Employee>
    @{
    ViewBag.Title = "Employee Information";
    }
    <div class="jumbotron">
    <table class="table table-bordered">
    <thead>
    <tr>
    <th>@Html.DisplayNameFor(model => model.Name)</th>
    <th>@Html.DisplayNameFor(model => model.Surname)</th>
    <th>@Html.DisplayNameFor(model => model.Address)</th>
    <th>@Html.DisplayNameFor(model => model.Telephone)</th>
    </tr>
    </thead>
    <tbody>
    @foreach (var item in Model)
    {
    <tr>
    <td>@Html.DisplayFor(model => item.Name)</td>
    <td>@Html.DisplayFor(model => item.Surname)</td>
    <td>@Html.DisplayFor(model => item.Address)</td>
    <td>@Html.DisplayFor(model => item.Telephone)</td>
    </tr>
    }
    <tr>
    <td>@Html.ActionLink("Previous", "Previous", null, new { @class = "btn btn-info"})</td>
    <td>@ViewBag.PageNumber</td>
    <td>@Html.ActionLink("Next", "Next", null, new { @class = "btn btn-info" })</td>
    </tr>
    </tbody>
    </table>
    </div>


    getEmployees SP with paging:



    create procedure getEmployees
    (
    @startRowIndex int,
    @maximumRows int
    )
    AS

    declare @firstInt int, @startRow int
    if (@startRowIndex <= (select COUNT(EmployeeID) from dbo.[Employee]))
    begin
    set ROWCOUNT @startRowIndex

    select @firstInt = EmployeeID from dbo.[Employee] order by EmployeeID

    set ROWCOUNT @maximumRows

    select EmployeeID, Name, Surname, Address, Telephone
    from dbo.[Employee] where EmployeeID >= @firstInt order by EmployeeID

    set ROWCOUNT 0
    end
    GO


    getTotalEmployees SP:



    create procedure getTotalEmployees
    as

    select COUNT(EmployeeId) from dbo.[Employee] where [Status] = 1

    go









    share|improve this question


























      up vote
      2
      down vote

      favorite









      up vote
      2
      down vote

      favorite











      I am a beginner web developer and I have to do an exercise to show an Employee table using a WCF service, 10 entries at a time, with the paging of the table controlled by a stored procedure. What I would like to know is if the code complies with best practices, and how I can improve it?



      The service1.svc.cs class:



      public class Service1 : IService1
      {
      private string connection_string = ConfigurationManager.ConnectionStrings["EmployeeDB"].ConnectionString.ToString();

      public List<Employee> getEmployees(int startRowIndex, int maximumRows)
      {
      List<Employee> employees = new List<Employee>();
      SqlConnection connection = new SqlConnection(connection_string);

      SqlCommand command = new SqlCommand();
      command.CommandText = "getEmployees";
      command.CommandType = CommandType.StoredProcedure;
      command.Parameters.Add(new SqlParameter("@startRowIndex", startRowIndex));
      command.Parameters.Add(new SqlParameter("@maximumRows", maximumRows));

      try
      {
      connection.Open();
      SqlDataReader dr = command.ExecuteReader();

      while (dr.Read())
      {
      Employee employee = new Employee();
      employee.ID = Convert.ToInt32(dr["EmployeeID"]) == 0 ? 0 : Convert.ToInt32(dr["EmployeeID"]);
      employee.Name = dr["Name"].ToString() == string.Empty ? "" : dr["Name"].ToString();
      employee.Surname = dr["Surname"].ToString() == string.Empty ? "" : dr["Surname"].ToString();
      employee.Address = dr["Address"].ToString() == string.Empty ? "" : dr["Address"].ToString();
      employee.Telephone = dr["Telephone"].ToString() == string.Empty ? "" : dr["Telephone"].ToString();
      employees.Add(employee);
      }
      connection.Close();
      return employees;
      }
      catch (Exception e) { throw e; }
      }
      public int getTotalEmployees()
      {
      int total = 0;

      using (SqlConnection connection = new SqlConnection(connection_string))
      {
      SqlCommand command = new SqlCommand();
      command.CommandText = "getTotalEmployees";
      command.CommandType = CommandType.StoredProcedure;
      try
      {
      connection.Open();
      total = Convert.ToInt32(command.ExecuteScalar());
      }
      catch (Exception ex) { throw ex; }
      }
      return total;
      }
      }


      The service interface:



      [ServiceContract]
      public interface IService1
      {
      [OperationContract]
      List<Employee> getEmployees(int startRowIndex, int maximumRows);
      [OperationContract]
      int getTotalEmployees();
      }

      [DataContract]
      public class Employee
      {
      [DataMember]
      public int ID { get; set; }
      [DataMember]
      public string Name { get; set; }
      [DataMember]
      public string Surname { get; set; }
      [DataMember]
      public string Address { get; set; }
      [DataMember]
      public string Telephone { get; set; }
      }


      Data Access Layer:



      public class DALEmployee
      {
      EmployeeService.Service1Client client = new EmployeeService.Service1Client();
      public List<Employee> getEmployees(int startRowIndex, int maximumRows)
      {
      List<Employee> employees = new List<Employee>();
      var employeeData = client.getEmployees(startRowIndex, maximumRows);
      if (employeeData.Count() > 0)
      {
      foreach (var item in employeeData)
      {
      Employee employee = new Employee() { ID = item.ID, Address = item.Address, Name = item.Name, Surname = item.Surname, Telephone = item.Telephone };
      employees.Add(employee);
      }
      }
      return employees;
      }
      public int getTotalEmployees()
      {
      return client.getTotalEmployees();
      }
      }


      Controller:



      public class HomeController : Controller
      {
      private EmployeeService.Service1Client client = new EmployeeService.Service1Client();
      int maximumRows = 10;

      public ActionResult Index()
      {
      double startRowIndex = Convert.ToDouble(Session["startRowIndex"]) == 0 ? 1 : Convert.ToDouble(Session["startRowIndex"]);
      Session["startRowIndex"] = startRowIndex;
      int totalEmployees = new DALEmployee().getTotalEmployees();
      ViewBag.PageNumber = Math.Floor(startRowIndex / maximumRows) == 0 ? 1 : Math.Floor(startRowIndex / maximumRows);
      List<Employee> employees = new DALEmployee().getEmployees(Convert.ToInt32(startRowIndex), maximumRows);
      return View(employees);
      }

      public ActionResult Next()
      {
      int startRowIndex = Convert.ToInt32(Session["startRowIndex"]) <= maximumRows ? 1 + maximumRows : Convert.ToInt32(Session["startRowIndex"]) + maximumRows;
      Session["startRowIndex"] = startRowIndex;
      return RedirectToAction("Index");
      }

      public ActionResult Previous()
      {
      int startRowIndex = Convert.ToInt32(Session["startRowIndex"]) <= maximumRows ? 1 : Convert.ToInt32(Session["startRowIndex"]) - maximumRows;
      Session["startRowIndex"] = startRowIndex;
      return RedirectToAction("Index");
      }
      }


      View:



      @model IEnumerable<ExerciseER.Models.Employee>
      @{
      ViewBag.Title = "Employee Information";
      }
      <div class="jumbotron">
      <table class="table table-bordered">
      <thead>
      <tr>
      <th>@Html.DisplayNameFor(model => model.Name)</th>
      <th>@Html.DisplayNameFor(model => model.Surname)</th>
      <th>@Html.DisplayNameFor(model => model.Address)</th>
      <th>@Html.DisplayNameFor(model => model.Telephone)</th>
      </tr>
      </thead>
      <tbody>
      @foreach (var item in Model)
      {
      <tr>
      <td>@Html.DisplayFor(model => item.Name)</td>
      <td>@Html.DisplayFor(model => item.Surname)</td>
      <td>@Html.DisplayFor(model => item.Address)</td>
      <td>@Html.DisplayFor(model => item.Telephone)</td>
      </tr>
      }
      <tr>
      <td>@Html.ActionLink("Previous", "Previous", null, new { @class = "btn btn-info"})</td>
      <td>@ViewBag.PageNumber</td>
      <td>@Html.ActionLink("Next", "Next", null, new { @class = "btn btn-info" })</td>
      </tr>
      </tbody>
      </table>
      </div>


      getEmployees SP with paging:



      create procedure getEmployees
      (
      @startRowIndex int,
      @maximumRows int
      )
      AS

      declare @firstInt int, @startRow int
      if (@startRowIndex <= (select COUNT(EmployeeID) from dbo.[Employee]))
      begin
      set ROWCOUNT @startRowIndex

      select @firstInt = EmployeeID from dbo.[Employee] order by EmployeeID

      set ROWCOUNT @maximumRows

      select EmployeeID, Name, Surname, Address, Telephone
      from dbo.[Employee] where EmployeeID >= @firstInt order by EmployeeID

      set ROWCOUNT 0
      end
      GO


      getTotalEmployees SP:



      create procedure getTotalEmployees
      as

      select COUNT(EmployeeId) from dbo.[Employee] where [Status] = 1

      go









      share|improve this question















      I am a beginner web developer and I have to do an exercise to show an Employee table using a WCF service, 10 entries at a time, with the paging of the table controlled by a stored procedure. What I would like to know is if the code complies with best practices, and how I can improve it?



      The service1.svc.cs class:



      public class Service1 : IService1
      {
      private string connection_string = ConfigurationManager.ConnectionStrings["EmployeeDB"].ConnectionString.ToString();

      public List<Employee> getEmployees(int startRowIndex, int maximumRows)
      {
      List<Employee> employees = new List<Employee>();
      SqlConnection connection = new SqlConnection(connection_string);

      SqlCommand command = new SqlCommand();
      command.CommandText = "getEmployees";
      command.CommandType = CommandType.StoredProcedure;
      command.Parameters.Add(new SqlParameter("@startRowIndex", startRowIndex));
      command.Parameters.Add(new SqlParameter("@maximumRows", maximumRows));

      try
      {
      connection.Open();
      SqlDataReader dr = command.ExecuteReader();

      while (dr.Read())
      {
      Employee employee = new Employee();
      employee.ID = Convert.ToInt32(dr["EmployeeID"]) == 0 ? 0 : Convert.ToInt32(dr["EmployeeID"]);
      employee.Name = dr["Name"].ToString() == string.Empty ? "" : dr["Name"].ToString();
      employee.Surname = dr["Surname"].ToString() == string.Empty ? "" : dr["Surname"].ToString();
      employee.Address = dr["Address"].ToString() == string.Empty ? "" : dr["Address"].ToString();
      employee.Telephone = dr["Telephone"].ToString() == string.Empty ? "" : dr["Telephone"].ToString();
      employees.Add(employee);
      }
      connection.Close();
      return employees;
      }
      catch (Exception e) { throw e; }
      }
      public int getTotalEmployees()
      {
      int total = 0;

      using (SqlConnection connection = new SqlConnection(connection_string))
      {
      SqlCommand command = new SqlCommand();
      command.CommandText = "getTotalEmployees";
      command.CommandType = CommandType.StoredProcedure;
      try
      {
      connection.Open();
      total = Convert.ToInt32(command.ExecuteScalar());
      }
      catch (Exception ex) { throw ex; }
      }
      return total;
      }
      }


      The service interface:



      [ServiceContract]
      public interface IService1
      {
      [OperationContract]
      List<Employee> getEmployees(int startRowIndex, int maximumRows);
      [OperationContract]
      int getTotalEmployees();
      }

      [DataContract]
      public class Employee
      {
      [DataMember]
      public int ID { get; set; }
      [DataMember]
      public string Name { get; set; }
      [DataMember]
      public string Surname { get; set; }
      [DataMember]
      public string Address { get; set; }
      [DataMember]
      public string Telephone { get; set; }
      }


      Data Access Layer:



      public class DALEmployee
      {
      EmployeeService.Service1Client client = new EmployeeService.Service1Client();
      public List<Employee> getEmployees(int startRowIndex, int maximumRows)
      {
      List<Employee> employees = new List<Employee>();
      var employeeData = client.getEmployees(startRowIndex, maximumRows);
      if (employeeData.Count() > 0)
      {
      foreach (var item in employeeData)
      {
      Employee employee = new Employee() { ID = item.ID, Address = item.Address, Name = item.Name, Surname = item.Surname, Telephone = item.Telephone };
      employees.Add(employee);
      }
      }
      return employees;
      }
      public int getTotalEmployees()
      {
      return client.getTotalEmployees();
      }
      }


      Controller:



      public class HomeController : Controller
      {
      private EmployeeService.Service1Client client = new EmployeeService.Service1Client();
      int maximumRows = 10;

      public ActionResult Index()
      {
      double startRowIndex = Convert.ToDouble(Session["startRowIndex"]) == 0 ? 1 : Convert.ToDouble(Session["startRowIndex"]);
      Session["startRowIndex"] = startRowIndex;
      int totalEmployees = new DALEmployee().getTotalEmployees();
      ViewBag.PageNumber = Math.Floor(startRowIndex / maximumRows) == 0 ? 1 : Math.Floor(startRowIndex / maximumRows);
      List<Employee> employees = new DALEmployee().getEmployees(Convert.ToInt32(startRowIndex), maximumRows);
      return View(employees);
      }

      public ActionResult Next()
      {
      int startRowIndex = Convert.ToInt32(Session["startRowIndex"]) <= maximumRows ? 1 + maximumRows : Convert.ToInt32(Session["startRowIndex"]) + maximumRows;
      Session["startRowIndex"] = startRowIndex;
      return RedirectToAction("Index");
      }

      public ActionResult Previous()
      {
      int startRowIndex = Convert.ToInt32(Session["startRowIndex"]) <= maximumRows ? 1 : Convert.ToInt32(Session["startRowIndex"]) - maximumRows;
      Session["startRowIndex"] = startRowIndex;
      return RedirectToAction("Index");
      }
      }


      View:



      @model IEnumerable<ExerciseER.Models.Employee>
      @{
      ViewBag.Title = "Employee Information";
      }
      <div class="jumbotron">
      <table class="table table-bordered">
      <thead>
      <tr>
      <th>@Html.DisplayNameFor(model => model.Name)</th>
      <th>@Html.DisplayNameFor(model => model.Surname)</th>
      <th>@Html.DisplayNameFor(model => model.Address)</th>
      <th>@Html.DisplayNameFor(model => model.Telephone)</th>
      </tr>
      </thead>
      <tbody>
      @foreach (var item in Model)
      {
      <tr>
      <td>@Html.DisplayFor(model => item.Name)</td>
      <td>@Html.DisplayFor(model => item.Surname)</td>
      <td>@Html.DisplayFor(model => item.Address)</td>
      <td>@Html.DisplayFor(model => item.Telephone)</td>
      </tr>
      }
      <tr>
      <td>@Html.ActionLink("Previous", "Previous", null, new { @class = "btn btn-info"})</td>
      <td>@ViewBag.PageNumber</td>
      <td>@Html.ActionLink("Next", "Next", null, new { @class = "btn btn-info" })</td>
      </tr>
      </tbody>
      </table>
      </div>


      getEmployees SP with paging:



      create procedure getEmployees
      (
      @startRowIndex int,
      @maximumRows int
      )
      AS

      declare @firstInt int, @startRow int
      if (@startRowIndex <= (select COUNT(EmployeeID) from dbo.[Employee]))
      begin
      set ROWCOUNT @startRowIndex

      select @firstInt = EmployeeID from dbo.[Employee] order by EmployeeID

      set ROWCOUNT @maximumRows

      select EmployeeID, Name, Surname, Address, Telephone
      from dbo.[Employee] where EmployeeID >= @firstInt order by EmployeeID

      set ROWCOUNT 0
      end
      GO


      getTotalEmployees SP:



      create procedure getTotalEmployees
      as

      select COUNT(EmployeeId) from dbo.[Employee] where [Status] = 1

      go






      c# beginner sql-server asp.net-mvc pagination






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Oct 4 '17 at 6:08









      200_success

      127k15148411




      127k15148411










      asked Oct 4 '17 at 4:51









      PatoPan

      112




      112






















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          2
          down vote













          The main things that I consider wrong or I don't fully get.



          service1




          • Probably is just a test case but if not, never name classes in that way.

          • The try/catch/throw makes no sense to me. You can simply remove them.


          • SqlConnection, Command and reader should always be used within a using clause.


          DALEmployee



          What is the concept behind this class? Do you really need it?
          If yes, my recommendation would be to inject IService1. You can google dependency injection to get more details.



          Controller



          If you don't need DALEmployee, you can simply inject IService1 directly in the controller.



          getEmployees



          Generally is weird to me how you achieve the pagination. Generally i would use as parameters CurrentPage and PageSize and for me it seems you that you are using the employee id. How would you extend this if you have to sort by other criteria rather than employee id? Additionaly, you are using a different where on the get count and on the procedure itself, what will lead to wrong pages.
          Finally, depending on your sql server version, you may use this operators to paginate.



          SELECT * FROM TableName ORDER BY whatever OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;






          share|improve this answer




























            up vote
            2
            down vote













            I can't speak to the application code but I can comment on the stored procedures and hopefully help a little in that area...



            @oromrub beat me to the punch with regard to the use of the offset fetch...



            Here is how I would typically lay out a stored procedure & why...



            -- SET ANSI_NULLS & QUOTED_IDENTIFIER ON...
            -- The server "should have these set as the default
            -- but it's still a good idea to set them yourself
            -- at the procedure level.
            SET ANSI_NULLS ON;
            GO
            SET QUOTED_IDENTIFIER ON;
            GO
            CREATE PROCEDURE dbo.GetEmployees
            /* =========================================================================================================
            10/5/2017 Your Name or Initials, The reason for the procedures existance. Commenting you code is important.
            ========================================================================================================= */
            /* -- sample execution --
            EXEC dbo.GetEmployees
            @PageNumber = 1,
            @RowsPerPage = 30
            */
            @PageNumber INT = 1,
            @RowsPerPage INT = 30
            AS
            BEGIN
            SET NOCOUNT ON; -- (SET NOCOUNT ON prevents the sending of DONE_IN_PROC messages to the client for each statement in a stored procedure.)

            SELECT
            e.EmployeeId,
            e.FirstName,
            e.LastName
            FROM
            dbo.Employee e
            ORDER BY
            e.EmployeeId
            OFFSET (@PageNumber - 1) * (@RowsPerPage + 1) ROWS FETCH NEXT @RowsPerPage ROWS ONLY;
            END;
            GO


            Here are a few things that should become automatic... Staring from the top...



            1) Comment your code! Don't expect to remember why you coded something the way you did a year from now. I like having a dedicated section at the top so it's always easy to figure out what the proc is for, when it was initially created and what revisions have been made over time. Plus it's just a common courtesy for the people you'll be working with.



            2) Set NOCOUNT ON; The count messages that SQL Server sends back to let you know how many rows you've affected is fine while you're working SSMS but you don't want them going back to you application.



            3) Use aliases!!! Forums are littered with the panicked cries of people who can't figure out why their query is inexplicable returning data that it shouldn't. Here's an example I pulled from an article on simple talk...



            SELECT sale_date, sale_amount
            FROM Sales AS S
            WHERE sale_date IN (SELECT sale_date
            FROM Calendar AS C
            WHERE holiday_name IS NOT NULL);


            Even if that wasn't as issue, it would still be important. Once you get more than a few tables joined in a query, it can be a real pain trying to decipher which columns come from which tables.



            5) Always include the schema name when referencing a table. For one, it helps SQL Server by saving if from having to check different schemas.



            The real biggie... You're querying the same table 3 times to do something really simple. As a rule, you want you code to be as efficient as possible. That means don't make 3 calls to the same table when you can get what you need in one trip. It means a lot more than that, but that's way to broad a topic for a wee forum post.



            Anyway, best of luck with the exercise. Hopefully some of this was helpful.



            Cheers! :)






            share|improve this answer























              Your Answer





              StackExchange.ifUsing("editor", function () {
              return StackExchange.using("mathjaxEditing", function () {
              StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
              StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
              });
              });
              }, "mathjax-editing");

              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "196"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              convertImagesToLinks: false,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














               

              draft saved


              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f177106%2fmvc-simple-employee-table-with-paging-using-sp%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              2
              down vote













              The main things that I consider wrong or I don't fully get.



              service1




              • Probably is just a test case but if not, never name classes in that way.

              • The try/catch/throw makes no sense to me. You can simply remove them.


              • SqlConnection, Command and reader should always be used within a using clause.


              DALEmployee



              What is the concept behind this class? Do you really need it?
              If yes, my recommendation would be to inject IService1. You can google dependency injection to get more details.



              Controller



              If you don't need DALEmployee, you can simply inject IService1 directly in the controller.



              getEmployees



              Generally is weird to me how you achieve the pagination. Generally i would use as parameters CurrentPage and PageSize and for me it seems you that you are using the employee id. How would you extend this if you have to sort by other criteria rather than employee id? Additionaly, you are using a different where on the get count and on the procedure itself, what will lead to wrong pages.
              Finally, depending on your sql server version, you may use this operators to paginate.



              SELECT * FROM TableName ORDER BY whatever OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;






              share|improve this answer

























                up vote
                2
                down vote













                The main things that I consider wrong or I don't fully get.



                service1




                • Probably is just a test case but if not, never name classes in that way.

                • The try/catch/throw makes no sense to me. You can simply remove them.


                • SqlConnection, Command and reader should always be used within a using clause.


                DALEmployee



                What is the concept behind this class? Do you really need it?
                If yes, my recommendation would be to inject IService1. You can google dependency injection to get more details.



                Controller



                If you don't need DALEmployee, you can simply inject IService1 directly in the controller.



                getEmployees



                Generally is weird to me how you achieve the pagination. Generally i would use as parameters CurrentPage and PageSize and for me it seems you that you are using the employee id. How would you extend this if you have to sort by other criteria rather than employee id? Additionaly, you are using a different where on the get count and on the procedure itself, what will lead to wrong pages.
                Finally, depending on your sql server version, you may use this operators to paginate.



                SELECT * FROM TableName ORDER BY whatever OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;






                share|improve this answer























                  up vote
                  2
                  down vote










                  up vote
                  2
                  down vote









                  The main things that I consider wrong or I don't fully get.



                  service1




                  • Probably is just a test case but if not, never name classes in that way.

                  • The try/catch/throw makes no sense to me. You can simply remove them.


                  • SqlConnection, Command and reader should always be used within a using clause.


                  DALEmployee



                  What is the concept behind this class? Do you really need it?
                  If yes, my recommendation would be to inject IService1. You can google dependency injection to get more details.



                  Controller



                  If you don't need DALEmployee, you can simply inject IService1 directly in the controller.



                  getEmployees



                  Generally is weird to me how you achieve the pagination. Generally i would use as parameters CurrentPage and PageSize and for me it seems you that you are using the employee id. How would you extend this if you have to sort by other criteria rather than employee id? Additionaly, you are using a different where on the get count and on the procedure itself, what will lead to wrong pages.
                  Finally, depending on your sql server version, you may use this operators to paginate.



                  SELECT * FROM TableName ORDER BY whatever OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;






                  share|improve this answer












                  The main things that I consider wrong or I don't fully get.



                  service1




                  • Probably is just a test case but if not, never name classes in that way.

                  • The try/catch/throw makes no sense to me. You can simply remove them.


                  • SqlConnection, Command and reader should always be used within a using clause.


                  DALEmployee



                  What is the concept behind this class? Do you really need it?
                  If yes, my recommendation would be to inject IService1. You can google dependency injection to get more details.



                  Controller



                  If you don't need DALEmployee, you can simply inject IService1 directly in the controller.



                  getEmployees



                  Generally is weird to me how you achieve the pagination. Generally i would use as parameters CurrentPage and PageSize and for me it seems you that you are using the employee id. How would you extend this if you have to sort by other criteria rather than employee id? Additionaly, you are using a different where on the get count and on the procedure itself, what will lead to wrong pages.
                  Finally, depending on your sql server version, you may use this operators to paginate.



                  SELECT * FROM TableName ORDER BY whatever OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Oct 4 '17 at 7:35









                  ogomrub

                  1464




                  1464
























                      up vote
                      2
                      down vote













                      I can't speak to the application code but I can comment on the stored procedures and hopefully help a little in that area...



                      @oromrub beat me to the punch with regard to the use of the offset fetch...



                      Here is how I would typically lay out a stored procedure & why...



                      -- SET ANSI_NULLS & QUOTED_IDENTIFIER ON...
                      -- The server "should have these set as the default
                      -- but it's still a good idea to set them yourself
                      -- at the procedure level.
                      SET ANSI_NULLS ON;
                      GO
                      SET QUOTED_IDENTIFIER ON;
                      GO
                      CREATE PROCEDURE dbo.GetEmployees
                      /* =========================================================================================================
                      10/5/2017 Your Name or Initials, The reason for the procedures existance. Commenting you code is important.
                      ========================================================================================================= */
                      /* -- sample execution --
                      EXEC dbo.GetEmployees
                      @PageNumber = 1,
                      @RowsPerPage = 30
                      */
                      @PageNumber INT = 1,
                      @RowsPerPage INT = 30
                      AS
                      BEGIN
                      SET NOCOUNT ON; -- (SET NOCOUNT ON prevents the sending of DONE_IN_PROC messages to the client for each statement in a stored procedure.)

                      SELECT
                      e.EmployeeId,
                      e.FirstName,
                      e.LastName
                      FROM
                      dbo.Employee e
                      ORDER BY
                      e.EmployeeId
                      OFFSET (@PageNumber - 1) * (@RowsPerPage + 1) ROWS FETCH NEXT @RowsPerPage ROWS ONLY;
                      END;
                      GO


                      Here are a few things that should become automatic... Staring from the top...



                      1) Comment your code! Don't expect to remember why you coded something the way you did a year from now. I like having a dedicated section at the top so it's always easy to figure out what the proc is for, when it was initially created and what revisions have been made over time. Plus it's just a common courtesy for the people you'll be working with.



                      2) Set NOCOUNT ON; The count messages that SQL Server sends back to let you know how many rows you've affected is fine while you're working SSMS but you don't want them going back to you application.



                      3) Use aliases!!! Forums are littered with the panicked cries of people who can't figure out why their query is inexplicable returning data that it shouldn't. Here's an example I pulled from an article on simple talk...



                      SELECT sale_date, sale_amount
                      FROM Sales AS S
                      WHERE sale_date IN (SELECT sale_date
                      FROM Calendar AS C
                      WHERE holiday_name IS NOT NULL);


                      Even if that wasn't as issue, it would still be important. Once you get more than a few tables joined in a query, it can be a real pain trying to decipher which columns come from which tables.



                      5) Always include the schema name when referencing a table. For one, it helps SQL Server by saving if from having to check different schemas.



                      The real biggie... You're querying the same table 3 times to do something really simple. As a rule, you want you code to be as efficient as possible. That means don't make 3 calls to the same table when you can get what you need in one trip. It means a lot more than that, but that's way to broad a topic for a wee forum post.



                      Anyway, best of luck with the exercise. Hopefully some of this was helpful.



                      Cheers! :)






                      share|improve this answer



























                        up vote
                        2
                        down vote













                        I can't speak to the application code but I can comment on the stored procedures and hopefully help a little in that area...



                        @oromrub beat me to the punch with regard to the use of the offset fetch...



                        Here is how I would typically lay out a stored procedure & why...



                        -- SET ANSI_NULLS & QUOTED_IDENTIFIER ON...
                        -- The server "should have these set as the default
                        -- but it's still a good idea to set them yourself
                        -- at the procedure level.
                        SET ANSI_NULLS ON;
                        GO
                        SET QUOTED_IDENTIFIER ON;
                        GO
                        CREATE PROCEDURE dbo.GetEmployees
                        /* =========================================================================================================
                        10/5/2017 Your Name or Initials, The reason for the procedures existance. Commenting you code is important.
                        ========================================================================================================= */
                        /* -- sample execution --
                        EXEC dbo.GetEmployees
                        @PageNumber = 1,
                        @RowsPerPage = 30
                        */
                        @PageNumber INT = 1,
                        @RowsPerPage INT = 30
                        AS
                        BEGIN
                        SET NOCOUNT ON; -- (SET NOCOUNT ON prevents the sending of DONE_IN_PROC messages to the client for each statement in a stored procedure.)

                        SELECT
                        e.EmployeeId,
                        e.FirstName,
                        e.LastName
                        FROM
                        dbo.Employee e
                        ORDER BY
                        e.EmployeeId
                        OFFSET (@PageNumber - 1) * (@RowsPerPage + 1) ROWS FETCH NEXT @RowsPerPage ROWS ONLY;
                        END;
                        GO


                        Here are a few things that should become automatic... Staring from the top...



                        1) Comment your code! Don't expect to remember why you coded something the way you did a year from now. I like having a dedicated section at the top so it's always easy to figure out what the proc is for, when it was initially created and what revisions have been made over time. Plus it's just a common courtesy for the people you'll be working with.



                        2) Set NOCOUNT ON; The count messages that SQL Server sends back to let you know how many rows you've affected is fine while you're working SSMS but you don't want them going back to you application.



                        3) Use aliases!!! Forums are littered with the panicked cries of people who can't figure out why their query is inexplicable returning data that it shouldn't. Here's an example I pulled from an article on simple talk...



                        SELECT sale_date, sale_amount
                        FROM Sales AS S
                        WHERE sale_date IN (SELECT sale_date
                        FROM Calendar AS C
                        WHERE holiday_name IS NOT NULL);


                        Even if that wasn't as issue, it would still be important. Once you get more than a few tables joined in a query, it can be a real pain trying to decipher which columns come from which tables.



                        5) Always include the schema name when referencing a table. For one, it helps SQL Server by saving if from having to check different schemas.



                        The real biggie... You're querying the same table 3 times to do something really simple. As a rule, you want you code to be as efficient as possible. That means don't make 3 calls to the same table when you can get what you need in one trip. It means a lot more than that, but that's way to broad a topic for a wee forum post.



                        Anyway, best of luck with the exercise. Hopefully some of this was helpful.



                        Cheers! :)






                        share|improve this answer

























                          up vote
                          2
                          down vote










                          up vote
                          2
                          down vote









                          I can't speak to the application code but I can comment on the stored procedures and hopefully help a little in that area...



                          @oromrub beat me to the punch with regard to the use of the offset fetch...



                          Here is how I would typically lay out a stored procedure & why...



                          -- SET ANSI_NULLS & QUOTED_IDENTIFIER ON...
                          -- The server "should have these set as the default
                          -- but it's still a good idea to set them yourself
                          -- at the procedure level.
                          SET ANSI_NULLS ON;
                          GO
                          SET QUOTED_IDENTIFIER ON;
                          GO
                          CREATE PROCEDURE dbo.GetEmployees
                          /* =========================================================================================================
                          10/5/2017 Your Name or Initials, The reason for the procedures existance. Commenting you code is important.
                          ========================================================================================================= */
                          /* -- sample execution --
                          EXEC dbo.GetEmployees
                          @PageNumber = 1,
                          @RowsPerPage = 30
                          */
                          @PageNumber INT = 1,
                          @RowsPerPage INT = 30
                          AS
                          BEGIN
                          SET NOCOUNT ON; -- (SET NOCOUNT ON prevents the sending of DONE_IN_PROC messages to the client for each statement in a stored procedure.)

                          SELECT
                          e.EmployeeId,
                          e.FirstName,
                          e.LastName
                          FROM
                          dbo.Employee e
                          ORDER BY
                          e.EmployeeId
                          OFFSET (@PageNumber - 1) * (@RowsPerPage + 1) ROWS FETCH NEXT @RowsPerPage ROWS ONLY;
                          END;
                          GO


                          Here are a few things that should become automatic... Staring from the top...



                          1) Comment your code! Don't expect to remember why you coded something the way you did a year from now. I like having a dedicated section at the top so it's always easy to figure out what the proc is for, when it was initially created and what revisions have been made over time. Plus it's just a common courtesy for the people you'll be working with.



                          2) Set NOCOUNT ON; The count messages that SQL Server sends back to let you know how many rows you've affected is fine while you're working SSMS but you don't want them going back to you application.



                          3) Use aliases!!! Forums are littered with the panicked cries of people who can't figure out why their query is inexplicable returning data that it shouldn't. Here's an example I pulled from an article on simple talk...



                          SELECT sale_date, sale_amount
                          FROM Sales AS S
                          WHERE sale_date IN (SELECT sale_date
                          FROM Calendar AS C
                          WHERE holiday_name IS NOT NULL);


                          Even if that wasn't as issue, it would still be important. Once you get more than a few tables joined in a query, it can be a real pain trying to decipher which columns come from which tables.



                          5) Always include the schema name when referencing a table. For one, it helps SQL Server by saving if from having to check different schemas.



                          The real biggie... You're querying the same table 3 times to do something really simple. As a rule, you want you code to be as efficient as possible. That means don't make 3 calls to the same table when you can get what you need in one trip. It means a lot more than that, but that's way to broad a topic for a wee forum post.



                          Anyway, best of luck with the exercise. Hopefully some of this was helpful.



                          Cheers! :)






                          share|improve this answer














                          I can't speak to the application code but I can comment on the stored procedures and hopefully help a little in that area...



                          @oromrub beat me to the punch with regard to the use of the offset fetch...



                          Here is how I would typically lay out a stored procedure & why...



                          -- SET ANSI_NULLS & QUOTED_IDENTIFIER ON...
                          -- The server "should have these set as the default
                          -- but it's still a good idea to set them yourself
                          -- at the procedure level.
                          SET ANSI_NULLS ON;
                          GO
                          SET QUOTED_IDENTIFIER ON;
                          GO
                          CREATE PROCEDURE dbo.GetEmployees
                          /* =========================================================================================================
                          10/5/2017 Your Name or Initials, The reason for the procedures existance. Commenting you code is important.
                          ========================================================================================================= */
                          /* -- sample execution --
                          EXEC dbo.GetEmployees
                          @PageNumber = 1,
                          @RowsPerPage = 30
                          */
                          @PageNumber INT = 1,
                          @RowsPerPage INT = 30
                          AS
                          BEGIN
                          SET NOCOUNT ON; -- (SET NOCOUNT ON prevents the sending of DONE_IN_PROC messages to the client for each statement in a stored procedure.)

                          SELECT
                          e.EmployeeId,
                          e.FirstName,
                          e.LastName
                          FROM
                          dbo.Employee e
                          ORDER BY
                          e.EmployeeId
                          OFFSET (@PageNumber - 1) * (@RowsPerPage + 1) ROWS FETCH NEXT @RowsPerPage ROWS ONLY;
                          END;
                          GO


                          Here are a few things that should become automatic... Staring from the top...



                          1) Comment your code! Don't expect to remember why you coded something the way you did a year from now. I like having a dedicated section at the top so it's always easy to figure out what the proc is for, when it was initially created and what revisions have been made over time. Plus it's just a common courtesy for the people you'll be working with.



                          2) Set NOCOUNT ON; The count messages that SQL Server sends back to let you know how many rows you've affected is fine while you're working SSMS but you don't want them going back to you application.



                          3) Use aliases!!! Forums are littered with the panicked cries of people who can't figure out why their query is inexplicable returning data that it shouldn't. Here's an example I pulled from an article on simple talk...



                          SELECT sale_date, sale_amount
                          FROM Sales AS S
                          WHERE sale_date IN (SELECT sale_date
                          FROM Calendar AS C
                          WHERE holiday_name IS NOT NULL);


                          Even if that wasn't as issue, it would still be important. Once you get more than a few tables joined in a query, it can be a real pain trying to decipher which columns come from which tables.



                          5) Always include the schema name when referencing a table. For one, it helps SQL Server by saving if from having to check different schemas.



                          The real biggie... You're querying the same table 3 times to do something really simple. As a rule, you want you code to be as efficient as possible. That means don't make 3 calls to the same table when you can get what you need in one trip. It means a lot more than that, but that's way to broad a topic for a wee forum post.



                          Anyway, best of luck with the exercise. Hopefully some of this was helpful.



                          Cheers! :)







                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited 21 hours ago

























                          answered Oct 5 '17 at 6:55









                          Jason A. Long

                          1313




                          1313






























                               

                              draft saved


                              draft discarded



















































                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f177106%2fmvc-simple-employee-table-with-paging-using-sp%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Costa Masnaga

                              Fotorealismo

                              Sidney Franklin