EF框架基础

ORM概述:

ORM全称是“对象 - 关系映射” 。

ORM是将关系数据库中的数据用对象的形式表现出来,并通过面向对象的方式将这些对象组织起来,实现系统业务逻辑的过程。

Entity Framework(简称EF):

ASP.NET MVC应用程序推荐使用的ORM框架;

支持多种数据库;

映射引擎支持存储过程;

提供Visual Studio集成工具,执行可视化操作;

一、资料准备

本教程使用具体实例进行演示EF的基本使用,需要用数据库以及一些工具类。

数据表结构脚本:

create table Dept --部门信息
(
	DeptId int primary key identity(1,1),
	DeptName varchar(50) not null
)

create table Employee	--员工信息
(
	EmpId int primary key identity(1,1),
	DeptId int not null,
	EmpName varchar(50) not null,
	EmpPhone varchar(50) not null,
	EmpArea varchar(50) not null,
	EmpSalary decimal(18,2) not null
)

insert into Dept(DeptName) values('开发部')
insert into Dept(DeptName) values('测试部')
insert into Dept(DeptName) values('实施部')

insert into Employee(DeptId,EmpName,EmpPhone,EmpArea,EmpSalary)
values(1,'刘德华','13887855552','武汉',6500)
insert into Employee(DeptId,EmpName,EmpPhone,EmpArea,EmpSalary)
values(2,'张学友','13556528634','深圳',6500)
insert into Employee(DeptId,EmpName,EmpPhone,EmpArea,EmpSalary)
values(3,'刘亦菲','13448494546','广州',6500)
insert into Employee(DeptId,EmpName,EmpPhone,EmpArea,EmpSalary)
values(1,'周杰伦','13888666855','北京',6500)
insert into Employee(DeptId,EmpName,EmpPhone,EmpArea,EmpSalary)
values(2,'许巍','13868654219','上海',6500)
insert into Employee(DeptId,EmpName,EmpPhone,EmpArea,EmpSalary)
values(3,'孙燕姿','13895133572','成都',6500)
insert into Employee(DeptId,EmpName,EmpPhone,EmpArea,EmpSalary)
values(1,'朴树','13458788896','武汉',6500)
insert into Employee(DeptId,EmpName,EmpPhone,EmpArea,EmpSalary)
values(2,'周润发','13554588745','南京',6500)
insert into Employee(DeptId,EmpName,EmpPhone,EmpArea,EmpSalary)
values(3,'李连杰','13998759654','上海',6500)

select * from Dept;
select * from Employee;

匿名类集合转动态属性:

public class MyDynamic
{
    public static List ToExpandoList(object query)
    {
        List listExpando = new List();
        foreach (var entity in (IEnumerable)query)
        {
            Type type = entity.GetType();
            dynamic dyEntity = new ExpandoObject();
            IDictionary dict = new Dictionary();
            dict = dyEntity as ExpandoObject;
            PropertyInfo[] arrProperty = type.GetProperties();
            foreach (PropertyInfo prop in arrProperty)
            {
                string a = prop.Name;
                string b = prop.GetValue(entity, null).ToString();
                dict.Add(prop.Name, prop.GetValue(entity, null));
            }
            listExpando.Add(dict as dynamic);
        }
        return listExpando;
    }
}

二、EF实现增删改查

在控制器中创建数据库操作类对象:

DBTESTEntities db = new DBTESTEntities();

(1)实现数据列表

Action:

public ActionResult Index()
{     
        	   
    var listView = from emp in db.Employee
                    join dept in db.Dept on emp.DeptId equals dept.DeptId
                    select new
                    {
                        EmpId = emp.EmpId,
                        DeptId = emp.DeptId,
                        DeptName = dept.DeptName,
                        EmpName = emp.EmpName,
                        EmpPhone = emp.EmpPhone,
                        EmpArea = emp.EmpArea,
                        EmpSalary = emp.EmpSalary
                    };
    ViewBag.listView = MyDynamic.ToExpandoList(listView);
    return View();
}

View:



    
    Index
    


    

查询员工信息

添加员工

@foreach (var item in ViewBag.listView) { }
员工编号 部门名称 员工姓名 员工电话 所在地区 员工工资 操作
@item.EmpId @item.DeptName @item.EmpName @item.EmpPhone @item.EmpArea @item.EmpSalary.ToString("F2") 编辑 | 删除

(2)实现数据新增

新增页面Action:

public ActionResult AddForm()
{
    //查询所有部门
    ViewBag.listDept = db.Dept.ToList();
    return View();
}

新增页面视图:



    
    AddForm
    


    
员工新增
所属部门:
员工姓名:
员工电话:
所在城市:
月薪:
返回首页

处理新增提交请求的Action:

public ActionResult Add()
{
    //执行添加操作
    //Employee emp = new Employee();
    //emp.DeptId = int.Parse(Request["DeptId"]);
    //emp.EmpName = Request["txtRealName"];
    //emp.EmpPhone = Request["txtPhone"];
    //emp.EmpArea = Request["txtArea"];
    //emp.EmpSalary = decimal.Parse(Request["txtSalary"]);
    //db.Employee.Add(emp);
    //db.SaveChanges();

    //EF框架执行sql语句
    string sql = "insert into Employee(DeptId,EmpName,EmpPhone,EmpArea,EmpSalary) values(@DeptId,@EmpName,@EmpPhone,@EmpArea,@EmpSalary)";
    SqlParameter DeptId = new SqlParameter("@DeptId", int.Parse(Request["DeptId"]));
    SqlParameter EmpName = new SqlParameter("@EmpName", Request["txtRealName"]);
    SqlParameter EmpPhone = new SqlParameter("@EmpPhone", Request["txtPhone"]);
    SqlParameter EmpArea = new SqlParameter("@EmpArea", Request["txtArea"]);
    SqlParameter EmpSalary = new SqlParameter("@EmpSalary", decimal.Parse(Request["txtSalary"]));
    int rowCount = db.Database.ExecuteSqlCommand(sql,DeptId, EmpName, EmpPhone, EmpArea, EmpSalary);
    return Content("", "text/html");
}

(3)实现数据编辑修改

编辑页面Action:

public ActionResult UpdateForm()
{
    //查询所有部门
    ViewBag.listDept = db.Dept.ToList();
    //查询员工详情
    ViewBag.emp = db.Employee.Find(int.Parse(Request["EmpId"]));          
    return View();
}

编辑页面视图:



    
    UpdateForm
    


    
员工修改
所属部门:
员工姓名:
员工电话:
所在城市:
月薪:
返回首页

处理修改请求的Action:

public ActionResult Update()
{
    //EF框架执行修改操作
    //int empId = int.Parse(Request["hdEmpId"]);
    //Employee emp = db.Employee.Find(empId);
    //emp.DeptId = int.Parse(Request["DeptId"]);
    //emp.EmpName = Request["txtRealName"];
    //emp.EmpPhone = Request["txtPhone"];
    //emp.EmpArea = Request["txtArea"];
    //emp.EmpSalary = decimal.Parse(Request["txtSalary"]);
    //db.SaveChanges();

    //EF框架执行sql语句
    int empId = int.Parse(Request["hdEmpId"]);
    string sql = "update Employee set DeptId=@DeptId,EmpName=@EmpName,EmpPhone=@EmpPhone,EmpArea=@EmpArea,EmpSalary=@EmpSalary where EmpId=@EmpId";
    SqlParameter DeptId = new SqlParameter("@DeptId", int.Parse(Request["DeptId"]));
    SqlParameter EmpName = new SqlParameter("@EmpName", Request["txtRealName"]);
    SqlParameter EmpPhone = new SqlParameter("@EmpPhone", Request["txtPhone"]);
    SqlParameter EmpArea = new SqlParameter("@EmpArea", Request["txtArea"]);
    SqlParameter EmpSalary = new SqlParameter("@EmpSalary", decimal.Parse(Request["txtSalary"]));
    SqlParameter EmpId = new SqlParameter("@EmpId", empId);
    int rowCount = db.Database.ExecuteSqlCommand(sql,DeptId, EmpName, EmpPhone, EmpArea, EmpSalary, EmpId);
    return Content("", "text/html");
}

(4)实现数据的删除

处理删除请求的Action:

public ActionResult Delete()
{
    //EF框架执行删除操作
    //int empId = int.Parse(Request["EmpId"]);
    //Employee emp = db.Employee.Find(empId);
    //db.Employee.Remove(emp);
    //db.SaveChanges();

    //EF框架执行SQL语句
    int empId = int.Parse(Request["EmpId"]);
    string sql = "delete from Employee where EmpId = @EmpId";
    SqlParameter EmpId = new SqlParameter("@EmpId", empId);
    int rowCount = db.Database.ExecuteSqlCommand(sql,EmpId);
    return Content("", "text/html");
}

三、组合条件搜索+分页

搜索页面Action:

public ActionResult SearchForm()
{
    var listView = from emp in db.Employee
                    join dept in db.Dept on emp.DeptId equals dept.DeptId
                    select new
                    {
                        EmpId = emp.EmpId,
                        DeptId = emp.DeptId,
                        DeptName = dept.DeptName,
                        EmpName = emp.EmpName,
                        EmpPhone = emp.EmpPhone,
                        EmpArea = emp.EmpArea,
                        EmpSalary = emp.EmpSalary
                    };
    //添加查询条件
    if (!string.IsNullOrEmpty(Request["ddlDept"]))
    {
        //linq to entity,不能在lambda里面进行int.parse,或者其它的显示隐式的转换,所以将类型转换写在外面 或者下述方案也可以解决
        //此处如果进行类型转换例如ToString(),int.Parse()会报错,可以上面的listView转换为LinqToObject,即db.Employee和db.Dept都调用AsEnumerable。
        int deptId = int.Parse(Request["ddlDept"]);
        listView = listView.Where(p => p.DeptId == deptId);
    }
    if (!string.IsNullOrEmpty(Request["txtRealName"]))
    {
        //linq to entity,不能在lambda里面进行int.parse,或者其它的显示隐式的转换
        string realName = Request["txtRealName"].ToString();
        listView = listView.Where(p => p.EmpName.Contains(realName));
    }

    //处理分页
    int pageSize = 5;  //页码大小
    int pageIndex = 1; //当前页码
    if (!string.IsNullOrEmpty(Request["page"]))
        pageIndex = int.Parse(Request["page"]);
    int recordCount = listView.Count();  //总记录条数量
    //总共页数
    int pageCount = recordCount % pageSize == 0 ? recordCount / pageSize : recordCount / pageSize + 1;
    if (pageIndex > pageCount) pageIndex = pageCount;
    if (pageIndex < 1) pageIndex = 1;
    listView = listView.OrderBy(p => p.EmpId).Skip(pageSize * (pageIndex - 1)).Take(pageSize);

    ViewBag.listView = MyDynamic.ToExpandoList(listView);
    //查询所有部门
    ViewBag.listDept = db.Dept.ToList();
    //记录页码大小,当前页和总页数
    ViewBag.pageSize = pageSize;
    ViewBag.pageIndex = pageIndex;
    ViewBag.pageCount = pageCount;
    return View();
}

搜索页面视图:



    
    多条件组合搜索+分页


    

查询员工信息

所属部门: 员工姓名:
@foreach (var item in ViewBag.listView) { }
员工编号 部门名称 员工姓名 员工电话 所在地区 员工工资
@item.EmpId @item.DeptName @item.EmpName @item.EmpPhone @item.EmpArea @item.EmpSalary.ToString("F2")
@{string urlParama = "ddlDept=" + Request["ddlDept"] + "&txtRealName=" + Request["txtRealName"];}
首页 上一页 下一页 末页 转到: 当前第@ViewBag.pageIndex页 共@ViewBag.pageCount

四、JPager插件实现分页

本案例同样实现组合条件+分页的功能,只是分页功能使用Jpager来实现,JPager插件可以在Nuget中进行安装。

安装完成后引入命名空间:

using JPager.Net;

Action:

public ActionResult Index(PagerInBase param)
{
    param.PageSize = 3;
    var list = from emp in db.Employee
                    join dept in db.Dept on emp.DeptId equals dept.DeptId
                    select new EmpAndDept
                    {
                        EmpId = emp.EmpId,
                        DeptId = emp.DeptId,
                        DeptName = dept.DeptName,
                        EmpName = emp.EmpName,
                        EmpPhone = emp.EmpPhone,
                        EmpArea = emp.EmpArea,
                        EmpSalary = emp.EmpSalary
                    };
    if (!string.IsNullOrEmpty(Request["DeptId"]))
    {
        int deptId = int.Parse(Request["DeptId"]);
        list = list.Where(p => p.DeptId == deptId);
    }
    if (!string.IsNullOrEmpty(Request["EmpName"]))
    {
        string EmpName = Request["EmpName"].ToString();
        list = list.Where(p => p.EmpName.Contains(EmpName));
    }

    var data = list.OrderBy(p=>p.EmpId).Skip(param.Skip).Take(param.PageSize);
    var count = list.Count();
    var res = new PagerResult
    {
        Code = 0,
        DataList = data,
        Total = count,
        PageSize = param.PageSize,
        PageIndex = param.PageIndex,
        RequestUrl = param.RequetUrl
    };
    ViewBag.ListDept = db.Dept;
    ViewBag.res = res;
    return View();
}

View:



    
    Index
    


    

查询员工信息

添加员工

部门: 姓名:

@foreach (var item in ViewBag.res.DataList) { }
员工编号 部门名称 员工姓名 员工电话 所在地区 员工工资 操作
@item.EmpId @item.DeptName @item.EmpName @item.EmpPhone @item.EmpArea @item.EmpSalary.ToString("F2") 编辑 | 删除
@Html.Raw(ViewBag.res.PagerHtml()) 共 @ViewBag.res.Total 条

五、PagedList插件实现分页

本案例同样实现组合条件+分页的功能,只是分页功能使用PagedList.MVC来实现,PagedList.MVC插件可以在Nuget中进行安装。

安装完成后引入命名空间:

using PagedList;

Action:

public ActionResult Index(int page = 1)
{
    var query = from emp in db.Employee
                join dept in db.Dept on emp.DeptId equals dept.DeptId
                select new EmpAndDept
                {
                    EmpId = emp.EmpId,
                    DeptId = emp.DeptId,
                    EmpName = emp.EmpName,
                    EmpPhone = emp.EmpPhone,
                    EmpArea = emp.EmpArea,
                    EmpSalary = emp.EmpSalary,
                    DeptName = dept.DeptName
                };
    //添加查询条件
    if (!string.IsNullOrEmpty(Request["DeptId"]))
    {
        //linq to entity,不能在lambda里面进行int.parse,或者其它的显示隐式的转换,所以将类型转换写在外面 或者下述方案也可以解决
        //此处如果进行类型转换例如ToString(),int.Parse()会报错,可以上面的listView转换为LinqToObject,即db.Employee和db.Dept都调用AsEnumerable。
        int deptId = int.Parse(Request["DeptId"]);
        query = query.Where(p => p.DeptId == deptId);
    }
    if (!string.IsNullOrEmpty(Request["EmpName"]))
    {
        //linq to entity,不能在lambda里面进行int.parse,或者其它的显示隐式的转换
        string realName = Request["EmpName"].ToString();
        query = query.Where(p => p.EmpName.Contains(realName));
    }
    int pagesize = 2;
    var data = query.OrderByDescending(p => p.EmpId).ToPagedList(page, pagesize);
    ViewBag.ListDept = db.Dept;
    ViewBag.DataList = data;
    return View();
}

View:

@using PagedList;
@using PagedList.Mvc;



    
    Index


    

查询员工信息

添加员工

部门: 姓名:

@foreach (var item in ViewBag.DataList) { }
员工编号 部门名称 员工姓名 员工电话 所在地区 员工工资 操作
@item.EmpId @item.DeptName @item.EmpName @item.EmpPhone @item.EmpArea @item.EmpSalary.ToString("F2") 编辑 | 删除
@Html.PagedListPager((IPagedList)ViewBag.DataList, page => Url.Action("Index", new { page, DeptId=Request["DeptId"], EmpName=Request["EmpName"] }))

六、EF中执行SQL查询

在EF中执行非查询操作,在前面的例子代码中已经出现过,此处不做描述,此处主要描述在EF中做SQL查询操作。

Action:

public ActionResult SqlQueryForm()
{
    DBTESTEntities db = new DBTESTEntities();
    var count = db.Database.SqlQuery("select count(*) from Employee");
    ViewBag.count = count.FirstOrDefault();

    var query1 = db.Database.SqlQuery("select * from Employee");
    ViewBag.listView1 = query1;
    
    //如果查询的结果找不到对应的实体,需要单独定义一个类,返回的数据必须数量和名字都与此类属性相同

    //如果查询出的数据需要修改,有如下2种方案
    //方案一:
    //Employee emp = db.Employee.SqlQuery("select * from Employee where EmpId = 1").FirstOrDefault();
    //emp.EmpSalary += 100;
    //db.SaveChanges();

    //方案二:
    //Employee emp = db.Database.SqlQuery("select * from Employee where EmpId = 1").FirstOrDefault();
    //emp.EmpSalary += 100;
    //db.Entry(emp).State = System.Data.Entity.EntityState.Modified;
    //db.SaveChanges();

    return View();
}

View:

使用EF中SQL语句进行查询员工数据,员工数量:@ViewBag.count

@foreach (var item in ViewBag.listView1) { }
员工编号 部门编号 员工姓名 员工电话 所在地区 员工工资
@item.EmpId @item.DeptId @item.EmpName @item.EmpPhone @item.EmpArea @item.EmpSalary.ToString("F2")

你可能感兴趣的:(EF框架基础)