目录
介绍
实体框架是一个对象关系映射器(ORM),它允许开发人员使用.NET对象处理数据库。它消除了对开发人员通常需要编写的大多数数据访问代码的需求。.NET Core附带了实体框架的新版本,即实体框架核心。EF Core是实体框架的轻量级跨平台版本。大多数顶级API保持不变,因此来自实体框架6.x的开发人员可以放心使用它,但有许多功能是EF 6.x的一部分,但不属于EF核心,例如复杂/值类型、没有联接实体的多对多关系、上次加载等。EF Core中引入了EF 66.x中缺少的一些新功能,例如影子状态属性、每个类型的表(TPT)、备用键。在本文中,我们将学习如何创建ASP.NET Core 1。使用实体框架核心1.0 的MVC应用程序。我们将创建一个EmployeeDetail
项目。在此项目中,我们将显示所有员工的列表,任何特定员工的详细信息,更新或删除员工的记录。稍后,我们还将添加排序,搜索操作的功能。
先决条件
在开始项目之前,我们必须具有以下配置:
- Visual Studio 2015 Update 3
- .NET Core
- SQL Server Management Studio
如果您已经拥有所有这些配置,那就太好了,否则请先配置所有这些要求。
创建 ASP.NET Core应用程序
打开Visual Studio并创建一个新的ASP.NET Core项目并将其命名为EmployeeDetail
。
从模板部分,选择项目的 Web应用程序模板,然后单击“确定”按钮。
成功创建项目后,您将获得以下项目结构:
现在按 F5 并运行应用程序。当我们运行这个应用程序时,我们将得到以下输出:
这是我们在应用程序中获得的默认屏幕。我们不需要这个默认屏幕,因此请从_layout
和Index
视图中删除不必要的代码。
现在转到_Layout
部分视图并用以下代码替换页面内容:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - EmployeeDetail</title>
<environment names="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</environment>
<environment names="Staging,Production">
<link rel="stylesheet"
href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only"
asp-fallback-test-property="position"
asp-fallback-test-value="absolute" />
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>
@Html.ApplicationInsightsJavaScript(TelemetryConfiguration)
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a asp-area="" asp-controller="Home" asp-action="Index"
class="navbar-brand">EmployeeDetail</a>
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© 2017 - EmployeeDetail</p>
</footer>
</div>
<environment names="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
</environment>
<environment names="Staging,Production">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
asp-fallback-test="window.jQuery">
</script>
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/bootstrap.min.js"
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
asp-fallback-test="window.jQuery && window.jQuery.fn &&
window.jQuery.fn.modal">
</script>
<script src="~/js/site.min.js" asp-append-version="true"></script>
</environment>
@RenderSection("scripts", required: false)
</body>
</html>
并将Index
视图内容替换为以下代码:
@{
ViewData["Title"] = "Home Page";
}
<div class="row">
<div class="col-md-12">
<h3>Employee Application</h3>
</div>
</div>
完成上述所有更改后,现在我们的应用程序将如下所示:
添加实体框架核心依赖项
在我们的应用程序中,我们将使用SQL Server作为数据库,因此我们需要安装SQL Server的实体框架。若要使用SQL Server,包为Microsoft.EntityFrameworkCore.SqlServer
。现在,我们在项目中添加实体框架的配置。
打开 Project.json 文件,并在依赖项部分下添加以下行。
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.0",
"Microsoft.EntityFrameworkCore.Tools": {
"version": "1.0.0-preview2-final",
"type": "build"
},
在下一步中,在“工具”部分添加以下行。
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final"
使用代码
创建实体类
添加实体框架的依赖项后,让我们创建Employee
和Project
实体类。将有多对一关系的Employee
和Project
实体,这意味着一个employee
一次只能处理一个project
,但一个project
可以有多个employee
。
员工实体
在模型文件夹中添加一个Employee
类,并将Employee
类的代码替换为以下代码:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace EmployeeDetail.Models
{
public class Employee
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int EmployeeId { get; set; }
public string EmployeeName { get; set; }
public string Designation { get; set; }
public string Skills { get; set; }
public int ProjectId { get; set; }
public Project Project { get; set; }
} }
在上面的代码中,EmployeeId
属性是Employee
实体的主键,也是标识类型。ProjectId
是外键,对应的导航属性是Project
。
项目实体
现在在 Model 文件夹中添加另一个类,并将此类命名为Project
,将此类中的代码替换为以下代码:
namespace EmployeeDetail.Models
{
public class Project
{
public int ProjectId { get; set; }
public string ProjectName { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}
}
该ProjectId
属性是此实体的主键,其他属性定义有关项目的信息。
添加数据库上下文类
任何实体框架结构的主类都是DbCntext
类。在此类中,我们定义用于在数据库中创建表的所有实体。现在在模型文件夹中添加另一个类并将其命名为EmployeeContext
。此类将从System.Data.Entity.DbContext
类派生。将此类中的代码替换为以下代码:
namespace EmployeeDetail.Models
{
public class EmployeeContext: DbContext
{
public EmployeeContext(DbContextOptions<EmployeeContext> options) : base(options)
{
}
public DbSet<Employee> Employee { get; set; }
public DbSet<Project> Project { get; set; }
}
}
在上面的代码中,我们为Employee
和Project
类定义了两个Dbset
属性。此属性将在数据库中创建两个表,并且名称将与Dbset
属性中定义的相同。
使用依赖关系注入注册上下文
创建所有实体和dbContext
类后,现在我们为实体框架添加一个服务,以便构造函数可以提供任何需要此服务的组件。在我们的控制器构造函数中,我们使用此服务来获取上下文实例。现在打开 startup.cs并将以下代码添加到ConfigureServices
方法中。
services.AddDbContext<EmployeeContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
在上面的代码中,我们为DbContext
注册了一个服务,此DefaultConnection
处提供在我们的 appsettings.json 中定义的连接字符串。现在打开 appsettings.json 文件并添加以下代码。将服务器名称替换为您的 SQL 服务器名称。
{
"ApplicationInsights": {
"InstrumentationKey": ""
},
"ConnectionStrings": {
"DefaultConnection": "Server=******;Database=Employee;
Trusted_Connection=True;MultipleActiveResultSets=true"
},
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}
添加迁移并创建数据库
配置实体和dbContext
类后,现在我们添加迁移并使用Update-Database
命令,我们将创建项目数据库。因此,首先添加迁移。打开“程序包管理器控制台”,运行“添加迁移优先迁移”命令。此命令将在项目中添加“迁移”文件夹,“迁移”文件夹中的第一个文件包含有关如何创建数据库的所有信息。
现在我们运行Update-Database
命令。此命令获取迁移类中可用的代码并更新数据库。在本例中,此命令在SQL Server中创建一个Employee
数据库,其中包含我们之前在model
类中定义的所有表和属性。
现在打开您的SQL Server,您会发现Employee
数据库已添加:
添加初始数据
现在我们的表和数据库已准备就绪。让我们在表中添加一些初始数据。
将数据添加到项目表
INSERT INTO dbo.Project
(
ProjectName,
StartDate,
EndDate
)
VALUES( N'Lions',CAST('02/01/2017' as datetime),_
CAST('04/05/2017' AS datetime) ),( _
N'OUP',CAST('08/09/2016' AS datetime),CAST('12/03/2017' AS datetime) ),
( N'VMesh',CAST('12/04/2016' as date),CAST('04/01/2017'as date) ),_
( N'IJFER Solution',CAST('01/03/2017' as datetime),CAST('05/01/2017' as datetime) )
将数据添加到Employee表
现在我们的数据库和应用程序设置已经准备就绪,让我们开始处理应用程序的控制器和视图部分。
Employee列表
完成所有配置后,现在我们开始处理项目的视图部分。首先,我们创建Employee
列表并显示员工的一些基本信息。
添加视图模型
ASP.NET MVC中的ViewModel用于仅显示所需信息。ViewModel还用于显示来自两个或多个模型的数据。现在我们在项目中添加一个ViewModel文件夹。在项目中添加一个新文件夹,并将其命名为 ViewModels。创建ViewModel文件夹后,在ViewModel文件夹中添加一个类。右键单击ViewModel文件夹并添加一个新类,将此类命名为Employee_Project
。创建类后,现在将以下代码粘贴到此类中。
public class Employee_Project
{
public int EmployeeId { get; set; }
public string EmployeeName { get; set; }
public string Designation { get; set; }
public string Project { get; set; }
}
在上面的代码中,我们添加了四个属性,前三个属性的值将从Employee
模型接收,第四个属性的值将从Project
模型接收。
现在转到HomeController
并将以下代码粘贴到Index
方法中。
public async Task<IActionResult> Index()
{
List<Employee_Project> ilIst = new List<Employee_Project>();
var listData = await (from emp in _context.Employee
join pro in _context.Project on emp.ProjectId
equals pro.ProjectId
select new
{
emp.EmployeeId,
emp.EmployeeName,
emp.Designation,
pro.ProjectName
}
).ToListAsync();
listData.ForEach(x =>
{
Employee_Project Obj = new Employee_Project();
Obj.EmployeeId = x.EmployeeId;
Obj.Designation = x.Designation;
Obj.EmployeeName = x.EmployeeName;
Obj.Project = x.ProjectName;
ilIst.Add(Obj);
});
return View(ilIst);
}
在上面的代码行中,我们创建了一个异步方法。异步编程是ASP.NET Core的默认模式。异步编程提供了一种在非阻塞模式下编写代码的机制。服务器的线程数量有限,在高负载情况下,如果所有线程都被阻塞并且服务器上到达新请求,则结果将被阻塞并停止响应。克服所有这些情况。.NET Core带有一种异步编程方法,我们可以在其中以异步方式为.NET Core MVC和EF core编写代码。结果将是高度响应和非阻塞的服务器应用程序。因此,在此项目中,我们将尝试以异步方式编写代码。
在上面的代码中,我们使用四个关键字async
、Task<IActionResult>
、await
和ToListAsync
,所有这些关键字都用于使方法异步。
async
关键字用于将方法定义为异步,此关键字告诉编译器为方法主体的各个部分生成回调并自动创建返回的Task<IActionResult>
对象。此处,Task<IActionResult>
将异步方法的返回类型定义为IActionResult
。await
关键字表示正在进行的工作,使用await
的异步方法必须由async
关键字修改,await
关键字告诉编译器等待执行await
中编写的表达式。ToListAsync
关键字是ToList
方法的异步版本,并尝试以异步方式执行表达式。
在上面的代码中,我们创建了一个异步索引方法。在第一行代码List<Employee_Project> ilIst
中,我们创建一个Employee_Project ViewModel
类型列表。使用Linq查询,我们获取有关所有员工的EmployeeId
、EmployeeName
、Designation
、ProjectName
信息,并使用ForEach
方法将这些值添加到iList
对象中。在最后一行代码中,我们将iList
返回给视图(return View(ilIst)
)。
在控制器中的Index
方法之后,现在打开Index
视图并将以下代码粘贴到Index
视图中。
@model IEnumerable<EmployeeDetail.ViewModels.Employee_Project>
@{
ViewData["Title"] = "Index";
}
<div class="row">
<div class="col-md-12">
<h3>Employee Application</h3>
</div>
</div>
<div class="row">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.EmployeeName)
</th>
<th>
@Html.DisplayNameFor(model => model.Designation)
</th>
<th>
@Html.DisplayNameFor(model => model.Project)
</th>
<th>
Action
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.EmployeeName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Designation)
</td>
<td>
@Html.DisplayFor(modelItem => item.Project)
</td>
<td>
<a asp-action="Detail" asp-controller="Home"
asp-route-Empid="@item.EmployeeId"
class="btn btn-primary">
Detail</a>
<a asp-action="Edit" asp-controller="Home"
asp-route-Empid="@item.EmployeeId"
class="btn btn-success">
Edit
</a>
<a asp-action="Delete" asp-controller="Home"
asp-route-Empid="@item.EmployeeId"
class="btn btn-danger">
Delete
</a>
</td>
</tr>
}
</table>
</div>
</div>
<div class="row">
<div class="col-md-12">
<a asp-action="NewEmployee" asp-controller="Home">
<button type="button" id="submit" class="btn btn-warning">
Add Employee</button>
</a>
</div>
</div>
在此index
视图中,我们获取Employee_Project ViewModel
的IEnumerable
对象并创建所有员工的列表。对于每个employee
条目,我们将添加Edit
、Delete
和Detail
选项。使用Edit
选项,我们将重定向到一个页面,我们可以在其中编辑employee
信息;使用Delete
选项,我们可以删除任何现有的employee
信息和使用Detail
选项,我们可以获取有关employee
的所有信息。我们还添加了一个“添加员工”按钮,使用该按钮我们可以添加新的员工条目。Index
方法Index
和视图的代码将创建以下屏幕:
添加新员工
我们应用程序的主页包含“添加员工”按钮,单击此按钮后,将打开一个新屏幕,我们可以在其中添加新的员工条目。现在在主控制器中创建NewEmployee
方法并将以下代码粘贴到此方法中:
public async Task<IActionResult> NewEmployee()
{
List<Project> project_ = new List<Project>();
var Project = await (from data in _context.Project
select new
{
ProjectId = data.ProjectId,
ProjectName = data.ProjectName
}).ToListAsync();
Project.ForEach(x =>
{
Project pro = new Project();
pro.ProjectId = x.ProjectId;
pro.ProjectName = x.ProjectName;
project_.Add(pro);
});
return View(project_);
}
在上面的代码中,我们创建了一个异步方法(NewEmployee
),在此方法中,我们获取所有项目的列表并返回此列表传给AddEmployee
视图。在使用此列表的视图页面上,我们创建一个包含所有项目名称的下拉列表。现在右键单击视图文件夹并添加一个新视图,将此视图命名为AddEmployee
。现在,将以下代码粘贴到此视图中。
<style>
.hidedata {
padding-top: 50px;
}
</style>
<div class="row">
<div class="col-md-12">
<div class="col-md-8 col-lg-offset-4">
<h3>Enter Employee Details</h3>
</div>
@{
List<SelectListItem> items=new List<SelectListItem>();
foreach (var data in Model)
{
items.Add(new SelectListItem()
{
Value = Convert.ToString(data.ProjectId),
Text = data.ProjectName
});
}
}
@using (@Html.BeginForm("AddEmployee","Home",FormMethod.Post))
{
<div class="row hidedata" id="hidDiv">
<div class="col-md-6 col-lg-offset-3">
<form class="form-horizontal">
<div class="form-group">
<label for="EmployeeName" class="col-sm-4 control-label">
Employee Name:</label>
<div class="col-sm-8">
<input type="text" class="form-control"
name="EmployeeName" placeholder="Employee Name">
</div>
</div>
<div class="form-group">
<label for="Designation" class="col-sm-4 control-label">
Designation:</label>
<div class="col-sm-8">
<input type="text" class="form-control"
name="Designation" placeholder="Designation">
</div>
</div>
<div class="form-group">
<label for="Skills" class="col-sm-4 control-label">
Skills:</label>
<div class="col-sm-8">
<input type="text" class="form-control"
name="Skills" placeholder="Employee Name">
</div>
</div>
<div class="form-group">
<label for="ProjectId" class="col-sm-4 control-label">
Project:</label>
<div class="col-sm-8">
@Html.DropDownList("ProjectId", items,
"---Select---", new { @class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-8">
<button type="submit" class="btn btn-info">Submit</button>
</div>
</div>
</form>
</div>
</div>
}
</div>
</div>
在上面的代码中,我们创建了一个SelectListItem
类型列表,并绑定了从控制器检索到的此列表中项目的所有值。使用Html.BeginForm
html助手,我们创建了一个html表单。在此表单中,我们为EmployeeName
、Designation
和Skills
属性创建了三个文本框,并为Projects
创建了一个下拉列表。在此下拉列表中,我们绑定之前创建的列表值。
在@Html.BeginForm
中,我们定义动作和控制器名称,表单的方法是POST
类型。当我们提交此表单时,所有字段值都将提交给控制器的AddEmployeeHome
操作。
现在,在Home
控制器中添加以下代码。
[HttpPost]
public IActionResult AddEmployee(IFormCollection form)
{
Employee Emp = new Employee();
Emp.EmployeeName = form["EmployeeName"].ToString();
Emp.ProjectId = int.Parse(form["ProjectId"].ToString());
Emp.Skills = form["Skills"].ToString();
Emp.Designation = form["Designation"].ToString();
_context.Employee.Add(Emp);
_context.SaveChanges();
return RedirectToAction("Index");
}
在这里,我们创建了AddEmployee
操作。请记住,我们已经有一个带有AddEmployee
名称的操作,但此操作的类型是POST
并且采用IFormCollection
类型的参数。此参数包含NewEmployee
视图form
部分中存在的所有控制器的值。在AddEmployee
的POST
方法中,我们从IformCollection
对象中获取所有控制器的值。此对象包含键值对形式的值。从IFormCollection
对象中获取所有值后,我们将这些值分配给Employee
对象并将此employee
对象添加到使用add
方法的_context.Employee
中。添加新的employee
后,我们将控件重定向到Index
操作。
获取员工详细信息
在索引视图中,我们显示所有员工的列表,每个employee
条目还包含“详细信息”按钮。
使用此按钮,我们可以获取employee
的所有信息。实际上,此按钮是锚标记,此锚标记包含控制器和操作名称。因此,当我们单击此锚标签时,它将重定向到Home
控制器的Detail
操作。我们希望显示特定员工的信息,因此我们需要将其employeeId
传递给我们的操作。在锚标签中,我们还定义了asp-route-Empid
属性,此属性会向URL字符串添加一个EmpId
参数。
<a asp-action="Detail" asp-controller="Home"
asp-route-Empid="@item.EmployeeId"
class="btn btn-primary">
Detail</a>
让我们在主控制器中添加一个Details
操作,并将以下代码粘贴到此操作中:
public async Task<IActionResult> Detail(int Empid)
{
EmployeeDetails Empobj = new EmployeeDetails();
var EmpDeatils = await (from emp in _context.Employee
join pro in _context.Project on
emp.ProjectId equals pro.ProjectId
where emp.EmployeeId==Empid
select new EmployeeDetails
{
EmployeeId= emp.EmployeeId,
EmployeeName= emp.EmployeeName,
Designation= emp.Designation,
Skills= emp.Skills,
ProjectName= pro.ProjectName,
StartDate= pro.StartDate,
EndDate= pro.EndDate
}
).FirstAsync();
return View(EmpDeatils);
}
在上面的代码中,我们创建了一个异步操作。此操作采用我们从索引视图传递的EmpId
参数。使用这个EmpId
,我们获取有关该employee
特定信息的所有信息并返回到Detail
视图。在第一行代码中,我们创建了一个EmployeeDetails
类对象,这里EmployeeDetails
是一个ViewModel
。我们需要创建一个ViewModel
,因为我们想显示员工的个人和项目级别信息。此信息与多个实体相关。因此,右键单击ViewModels文件夹,添加一个新类并将该类命名为EmployeeDetails
。创建类后,将以下代码粘贴到此类中。
namespace EmployeeDetail.ViewModels
{
public class EmployeeDetails
{
public int EmployeeId { get; set; }
public string EmployeeName { get; set; }
public string Designation { get; set; }
public string Skills { get; set; }
public string ProjectName { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}
}
在EmployeeDetail ViewModel
中,我们定义将在详细信息页面上显示的所有属性。在控制器和ViewModel
上工作后,现在我们向主文件夹添加新视图。右键单击主文件夹并添加新视图并将此视图命名为详细信息。创建视图后,现在将以下代码粘贴到视图中:
@model EmployeeDetail.ViewModels.EmployeeDetails
@{
ViewData["Title"] = "Index";
}
<style>
.row {
line-height: 30px;
font-size: 16px;
}
</style>
<div class="row">
<div class="col-md-12">
<h3>Employee Details</h3>
</div>
</div>
<div class="row">
<div class="col-md-3"><b>Employee Name:</b></div>
<div class="col-md-3">@Model.EmployeeName</div>
</div>
<div class="row">
<div class="col-md-3"><b>Designation:</b></div>
<div class="col-md-3">@Model.Designation</div>
</div>
<div class="row">
<div class="col-md-3"><b>Skills:</b></div>
<div class="col-md-3">@Model.Skills</div>
</div>
<div class="row">
<div class="col-md-3"><b>ProjectName:</b></div>
<div class="col-md-3">@Model.ProjectName</div>
</div>
<div class="row">
<div class="col-md-3"><b>Start Date:</b></div>
<div class="col-md-3">@Model.StartDate.Date</div>
</div>
<div class="row">
<div class="col-md-3"><b>End Date:</b></div>
<div class="col-md-3">@Model.EndDate.Date</div>
</div>
详细信息视图将显示employee
的个人和项目级别信息。例如,当我们单击Dheeraj Sharma
员工的详细信息按钮时,我们将重定向到Detail
页面,将显示以下结果。
更新员工详细信息
在employee
列表页面中,我们为每个employee
添加一个Edit
按钮。当任何用户单击此按钮时,它将重定向到HomeController
的Edit
操作,我们正在传递EmployeeId
参数。
<a asp-action="Edit" asp-controller="Home"
asp-route-Empid="@item.EmployeeId"
class="btn btn-success">
Edit
</a>
现在在HomeController
中添加以下代码。
public async Task<IActionResult> Edit(int Empid)
{
EmployeeInfo empData = new EmployeeInfo();
var empObj= await
_context.Employee
.Where(x => x.EmployeeId == Empid)
.FirstAsync();
empData.EmployeeId = empObj.EmployeeId;
empData.EmployeeName = empObj.EmployeeName;
empData.Skills = empObj.Skills;
empData.Designation = empObj.Designation;
empData.ProjectId = empObj.ProjectId;
var projectObj = _context.Project;
await projectObj.ForEachAsync(x=>{
empData.list.Add(new SelectListItem()
{ Text = x.ProjectName, Value = x.ProjectId.ToString() });
});
return View(empData);
}
在上面的代码中,我们创建了一个异步操作,返回的操作类型为Task<IActionResult>
。在代码的第一行中,我们正在创建EmployeeInfo
类的对象。我们在此对象中插入employee
详细信息和SelectListItem
类型列表。现在右键单击“Models”文件夹,添加一个新类并将该类命名为EmployeeInfo
。现在将以下代码粘贴到此类中:
public class EmployeeInfo
{
public int EmployeeId { get; set; }
public string EmployeeName { get; set; }
public string Designation { get; set; }
public string Skills { get; set; }
public int ProjectId { get; set; }
public List<SelectListItem> list = new List<SelectListItem>();
}
此类将用作我们Edit
视图的Model
类。在此类中,我们添加了一些属性和SelectListItem
类型列表。此列表包含所有项目名称。
在接下来的Edit
操作行中,我们提取了employee
详细信息和项目列表,并将所有这些值绑定到EmployeeDetails
类的empData
对象,在最后一行中,我们返回了该对象以供查看。
之后,现在右键单击“视图”文件夹,添加一个新视图并将此视图命名为Edit
并将以下代码粘贴到此视图中。
<style>
.hidedata {
padding-top: 50px;
}
</style>
<div class="row">
<div class="col-md-12">
<div class="col-md-8 col-lg-offset-4">
<h3>Edit Employee Details</h3>
</div>
@using (@Html.BeginForm("Edit", "Home", FormMethod.Post))
{
<div class="row hidedata" id="hidDiv">
<div class="col-md-6 col-lg-offset-3">
<form class="form-horizontal">
<div class="form-group">
<label for="EmployeeName"
class="col-sm-4 control-label">Employee Name:</label>
<div class="col-sm-8">
<input type="text" class="form-control"
value="@Model.EmployeeName" name="EmployeeName"
placeholder="Employee Name">
</div>
</div>
<div class="form-group">
<label for="Designation"
class="col-sm-4 control-label">Designation:</label>
<div class="col-sm-8">
<input type="text" class="form-control"
value="@Model.Designation" name="Designation"
placeholder="Designation">
</div>
</div>
<div class="form-group">
<label for="Skills" class="col-sm-4 control-label">
Skills:</label>
<div class="col-sm-8">
<input type="text" class="form-control"
value="@Model.Skills" name="Skills"
placeholder="Employee Name">
</div>
</div>
<div class="form-group">
<label for="ProjectId" class="col-sm-4 control-label">
Project:</label>
<div class="col-sm-8">
@Html.DropDownList("ProjectId",
new SelectList(Model.list,"Value",
"Text",Model.ProjectId) ,
"---Select---", new { @class = "form-control" })
</div>
</div>
<input type="hidden" name="EmployeeId"
value="@Model.EmployeeId"/>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-8">
<button type="submit"
class="btn btn-info">Submit</button>
</div>
</div>
</form>
</div>
</div>
}
</div>
</div>
上面的HTML代码创建了一个html表单,在这个表单中,我们添加了一些控制器。在初始状态下,所有这些控制器的值都填充了我们从Edit
操作返回的Model
数据。
任何修改后,当我们提交所有更改时,它将重定向到Home控制器的Edit
操作。现在,在HomeController
您的中添加如下代码。
[HttpPost]
public IActionResult Edit(IFormCollection form)
{
Employee emp = new Employee();
emp.EmployeeId = int.Parse(form["EmployeeId"]);
emp.Designation = form["Designation"];
emp.EmployeeName = form["EmployeeName"];
emp.ProjectId = int.Parse(form["ProjectId"]);
emp.Skills = form["Skills"];
_context.Entry(emp).State =
Microsoft.EntityFrameworkCore.EntityState.Modified;
_context.SaveChanges();
return RedirectToAction("Index");
}
在上面的代码中,我们从IformCollection
对象中获取所有信息,并将这些信息添加到Employee
对象中。使用此Employee
对象,我们将更新数据库的Employee
状态并将所有这些更改保存到数据库中。
删除员工条目
在Employee
列表页面中,我们可以选择删除任何employee
条目。当我们单击“删除”按钮时,它将重定向到Home
控制器的Delete
操作。我们还将Empid
参数传递给要删除的EmployeeId
。
<a asp-action="Delete" asp-controller="Home"
asp-route-Empid="@item.EmployeeId"
class="btn btn-danger">
Delete
</a>
现在,在您的HomeController
中添加如下代码。
public IActionResult Delete(int Empid)
{
Employee Emp;
Emp = _context.Employee.Where(x => x.EmployeeId == Empid).First();
_context.Employee.Remove(Emp);
_context.SaveChanges();
return RedirectToAction("Index");
}
在上面的代码行中,根据EmployeeId
值,我们获取Employee
对象并将其employee
从dbContext
中删除并将所有更改保存到数据库中。简而言之,上述所有代码都会删除该employee
条目并将所有更改保存在数据库中。
添加搜索框
现在我们在项目中添加搜索功能,为此我们将添加一个文本框和搜索按钮。我们对Employee
名称和项目名称进行搜索。将以下代码替换为Index
视图的代码。
@model IEnumerable<EmployeeDetail.ViewModels.Employee_Project>
@{
ViewData["Title"] = "Index";
}
<div class="row">
<div class="col-md-12">
<h3>Employee Application</h3>
</div>
</div>
<div class="row">
<div class="col-md-12">
<form asp-action="Search" >
<div class="form-actions no-color">
<p>
<input type="text" name="searchText" value="@ViewData["searchText"]" />
<input type="submit" value="Search" class="btn btn-primary" /> |
<a asp-action="Index">Show All</a>
</p>
</div>
</form>
</div>
</div>
<div class="row">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.EmployeeName)
</th>
<th>
@Html.DisplayNameFor(model => model.Designation)
</th>
<th>
@Html.DisplayNameFor(model => model.Project)
</th>
<th>
Action
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.EmployeeName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Designation)
</td>
<td>
@Html.DisplayFor(modelItem => item.Project)
</td>
<td>
<a asp-action="Detail" asp-controller="Home"
asp-route-Empid="@item.EmployeeId"
class="btn btn-primary">
Detail</a>
<a asp-action="Edit" asp-controller="Home"
asp-route-Empid="@item.EmployeeId"
class="btn btn-success">
Edit
</a>
<a asp-action="Delete" asp-controller="Home"
asp-route-Empid="@item.EmployeeId"
class="btn btn-danger">
Delete
</a>
</td>
</tr>
}
</table>
</div>
</div>
<div class="row">
<div class="col-md-12">
<a asp-action="NewEmployee" asp-controller="Home">
<button type="button" id="submit" class="btn btn-warning">
Add Employee</button>
</a>
</div>
</div>
对于搜索功能,我们添加了一个form
部分。在这个form
中,我们有一个textbox
,当我们插入一些文本到textbox
中并单击搜索按钮时,它将重定向到HomeController
的Search
操作。
<form asp-action="Search" >
<div class="form-actions no-color">
<p>
<input type="text" name="searchText" value="@ViewData["searchText"]" />
<input type="submit" value="Search" class="btn btn-primary" /> |
<a asp-action="Index">Show All</a>
</p>
</div>
</form>
现在在HomeController
中添加以下代码:
public async Task<IActionResult> Search(IFormCollection form)
{
if (form["searchText"].ToString() != "")
{
List<Employee_Project> ilIst = new List<Employee_Project>();
var listData = await(from emp in _context.Employee
join pro in _context.Project on
emp.ProjectId equals pro.ProjectId
where emp.EmployeeName.Contains
(form["searchText"].ToString())
||
pro.ProjectName.Contains
(form["searchText"].ToString())
select new
{
emp.EmployeeId,
emp.EmployeeName,
emp.Designation,
pro.ProjectName
}
).ToListAsync();
listData.ForEach(x =>
{
Employee_Project Obj = new Employee_Project();
Obj.EmployeeId = x.EmployeeId;
Obj.Designation = x.Designation;
Obj.EmployeeName = x.EmployeeName;
Obj.Project = x.ProjectName;
ilIst.Add(Obj);
});
return View("Index",ilIst);
}
else
{
return RedirectToAction("Index");
}
}
在上面的代码中,我们创建了一个异步类型的Search
操作。在此操作中,我们使用IFormCollection
对象来获取搜索文本框的值。如果值文本框不为空,则我们在Linq查询中执行等于SQL like
运算符的Contains
运算符。这个LINQ查询返回所有EmployeeName
或项目名称包含我们插入到textbox
中的文本的Employee
。
我们还有一个“全部显示”选项。使用此选项,我们可以获取所有员工的列表。
添加排序功能
添加搜索功能后,现在我们将在employee
列表中添加数据排序选项。我们将对Employee
名称执行排序操作。默认情况下,排序顺序将升序。因此,在索引操作中添加order by emp.EmployeeName ascending
行,我们将在其中获取员工列表。
此命令根据Employees
名称按顺序对数据进行ascending
排序。
在表的EmployeeName
header中添加以下代码行:
<a asp-action="Sort" asp-route-sortOrder="@ViewData["sortOrder"]">
<img src=@("/images/"+(ViewData["sortOrder"]!=null?ViewData
["sortOrder"]:"ascending")+".png") />
</a>
在上面的代码中,我们添加了一个图像,我们将显示ascending.png图像用于升序排序和descending.png图像用于降序排序。现在,在图像文件夹中为向上和向下箭头添加两个图像,并将这些图像重命名为descending.png和ascending.png。我们将使用这些图像来指示排序顺序。
现在在HomeController
中添加Sort
操作并在Sort
操作中复制以下代码。
public async Task<IActionResult> Sort(string sortOrder)
{
List<Employee_Project> ilIst = new List<Employee_Project>();
if (sortOrder == "ascending" || sortOrder == null)
{
ViewData["sortOrder"] = "descending";
var listData = await (from emp in _context.Employee
join pro in _context.Project
on emp.ProjectId equals pro.ProjectId
orderby emp.EmployeeName descending
select new
{
emp.EmployeeId,
emp.EmployeeName,
emp.Designation,
pro.ProjectName
}
).ToListAsync();
listData.ForEach(x =>
{
Employee_Project Obj = new Employee_Project();
Obj.EmployeeId = x.EmployeeId;
Obj.Designation = x.Designation;
Obj.EmployeeName = x.EmployeeName;
Obj.Project = x.ProjectName;
ilIst.Add(Obj);
});
return View("Index", ilIst);
}
else
{
ViewData["sortOrder"] = "ascending";
var listData = await (from emp in _context.Employee
join pro in _context.Project
on emp.ProjectId equals pro.ProjectId
orderby emp.EmployeeName ascending
select new
{
emp.EmployeeId,
emp.EmployeeName,
emp.Designation,
pro.ProjectName
}
).ToListAsync();
listData.ForEach(x =>
{
Employee_Project Obj = new Employee_Project();
Obj.EmployeeId = x.EmployeeId;
Obj.Designation = x.Designation;
Obj.EmployeeName = x.EmployeeName;
Obj.Project = x.ProjectName;
ilIst.Add(Obj);
});
return View("Index", ilIst);
}
}
根据sortOrder
参数的值,我们将执行orderBy
子句。当sortOrder
参数值升序或null
时,我们将按降序对员工列表进行排序并显示descending.png图像。
在else
语句中,我们按“升序”顺序对列表进行排序,并显示ascending.png图像。
https://www.codeproject.com/Articles/1176211/Getting-Started-with-ASP-NET-Core-and-Entity-Frame