Ajax请求asp.net MVC查出的列表数据转成DTO的实例

我们的示例数据库脚本:

USE [DB_USERS]
GO
/****** Object:  Table [dbo].[Student]    Script Date: 11/06/2015 00:01:52 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Student](
    [s_ID] [INT] IDENTITY(1,1) NOT NULL,
    [s_Name] [NVARCHAR](10) NULL,
    [s_Sex] [CHAR](2) NULL,
    [s_Age] [INT] NULL,
    [c_ID] [INT] NOT NULL,
 CONSTRAINT [PK__Studnet__2F3DA3BC267ABA7A] PRIMARY KEY CLUSTERED 
(
    [s_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Student]  WITH CHECK ADD FOREIGN KEY([c_ID])
REFERENCES [dbo].[Classes] ([c_ID])
GO
USE [DB_USERS]
GO
/****** Object:  Table [dbo].[Classes]    Script Date: 11/06/2015 00:02:15 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Classes](
    [c_ID] [INT] NOT NULL,
    [c_Name] [NVARCHAR](50) NULL,
PRIMARY KEY CLUSTERED 
(
    [c_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

然后新建MVC的项目:贴出框架图:

列表数据转成DTO的实例-">

后台的代码;
控制器的代码:
using MVCAjax01.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MVCAjax01.Controllers
{
    public class StudentController : Controller
    {
        ModelDB db = new ModelDB();
        /// <summary>
        /// 生成学员列表页面
        /// </summary>
        /// <returns></returns>
        public ActionResult Index()
        {
            return View();
        }
        /// <summary>
        /// 根据页码加载数据
        /// </summary>
        /// <param name="id">id参数其实传到页面中对应的pageIndex,那为什么用id,因为路由中是这么配置的</param>
        /// <returns></returns>
        public ActionResult List(int id)
        {
            int pageIndex = id;
            int pageSize = 3;
            //查询学员分页数据
            //分页的步骤:orderby-->Skip((页码-1)*页容量)--->Take(页容量),最后tolist().
            //List<Student> list = db.Students.OrderBy(s => s.s_ID).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            //换成DTO实体
            //这样写就有问题了,db.Students的Students还是Model下面的EFstudent实体,这个时候可以这样改一下。
            //List<MVCAjax01.Models.DTO.Student> list = db.Students.OrderBy(s => s.s_ID).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            //修正之后的(使用select方法映射一下,转成DTO,在里面要new一下每个DTO)
            //将EF查询出来的F实体集合转成DTO(data transfer object)实体集合
            //List<MVCAjax01.Models.DTO.Student> list = db.Students.OrderBy(s => s.s_ID).Skip((pageIndex - 1) * pageSize).Take(pageSize).Select(s => new Models.DTO.Student() { 
            //s_ID=s.s_ID,
            //s_Name=s.s_Name,
            //s_Age=s.s_Age,
            //s_Sex=s.s_Sex,
            //c_ID=s.c_ID,
            //Class=s.Class
            
            //}).ToList();    //TIPS:这里一个一个属性写太累了,我们可以写一个方法实体类转DTO的方法,在Model里添加一个类,写方法。
            //在分布类中写了DTO转化方法之后,这边就不用select了。直接这样写。
            //List<MVCAjax01.Models.DTO.Student> list = db.Students.OrderBy(s => s.s_ID).Skip((pageIndex - 1) * pageSize).Take(pageSize).Select(
            
            //   s=>s.ToDto()   //这样写还有个问题,就是Class属性刚才没有设置。这个时候还要做修改。
            //).ToList();
            //这个时候,可以这样修改,  但这样写还有问题,就是EF中的Class属性和DTO中的属性还是不一样,所以我们还是在DTO中做修改,同样我们需要为Class设置添加DTO类
            //List<MVCAjax01.Models.DTO.Student> list = db.Students.OrderBy(s => s.s_ID).Skip((pageIndex - 1) * pageSize).Take(pageSize).Select(
            //s => { var sDTO = s.ToDto(); sDTO.Class = s.Class; return sDTO; }
            
            //将EF查出来的集合转成DTO实体集合,并返回(关于使用DTO类的时候注意,类名不要和EF实体类一样,不然会报错。)
            //然后,这边还有一个易错点:take方法之后必须要tolist,不然报错。
            List<MVCAjax01.Models.DTO.StudentDTO> list = db.Students.OrderBy(s => s.s_ID).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList().Select(
          s =>s.ToDto()
         ).ToList();
            //获取总行数(总数)
            int rowCount = db.Students.Count();
            //计算总页数
            int pageCount = Convert.ToInt32(Math.Ceiling((rowCount * 1.0) / pageSize));
            //生成Json格式的数据(如果自己生成就很麻烦,这个时候就自己添加一个类,做法;我们在Model文件夹下添加一个类)
            #region 没有使用DTO的时候的版本
            //没有使用DTO的时候的版本
            ////操作:将数据封装到PagedDataModel 分页数据实体中
            ////封装很简单啊,就是给属性赋值呗:
            ////弄成泛型类之后,要指定是哪个类
            //PagedDataModel<Student> pageModel = new PagedDataModel<Student>()
            ////但不管怎么样,这个PagedDataModel实体中,仅仅是包含分页的数据相关的数据而已,那你转成Json格式的数据,你要把他转哇,
            ////发到浏览器去,浏览器肯定想知道,到底是成功还是没成功啊,状态是什么啊,所以我们还要准备一个类,这个时候就是JsonModel
            ////我们再在Model文件夹下添加一个JosnModel类
            //{
            //    //data属性弄成泛型之后,这边就可以直接将list赋值给data了。
            //    Data = list,
            //    PageCount = pageCount,
            //    PageSize = pageSize,
            //    RowCount = rowCount,
            //    PageIndex = pageSize
            //};
            #endregion
            #region 使用DTO之后的版本修改
            //操作:将数据封装到PagedDataModel 分页数据实体中
            //封装很简单啊,就是给属性赋值呗:
            //弄成泛型类之后,要指定是哪个类
            PagedDataModel<Models.DTO.StudentDTO> pageModel = new PagedDataModel<Models.DTO.StudentDTO>()
            //但不管怎么样,这个PagedDataModel实体中,仅仅是包含分页的数据相关的数据而已,那你转成Json格式的数据,你要把他转哇,
            //发到浏览器去,浏览器肯定想知道,到底是成功还是没成功啊,状态是什么啊,所以我们还要准备一个类,这个时候就是JsonModel
            //我们再在Model文件夹下添加一个JosnModel类
            {
                //data属性弄成泛型之后,这边就可以直接将list赋值给data了。
                Data = list,
                PageCount = pageCount,
                PageSize = pageSize,
                RowCount = rowCount,
                PageIndex = pageSize
            };
            
            //总结;上面的查询Student数据的时候,用EF查出来之后,转为了DTO的集合,(本来查出来的是EF的学员集合)
            #endregion
            //将分页数据实体,封装到json 标准格式实体中
            JsonModel jsonModel = new JsonModel()
            {
                Data = pageModel,
                Message = "成功",
                Status = "OK"
                //BackUrl=  不给,没东西嘛!
            };
            #region 这两行代码,相当于是json 方法
            // System.Web.Script.Serialization.JavaScriptSerializer jsS = new System.Web.Script.Serialization.JavaScriptSerializer();
            //string str= jsS.Serialize(list);
            #endregion
            //生成json格式的数据(通过json方法)
           //这个方法,内部其实就是帮我们调用JavaScriptSerializer的序列化方法,正是因为调用这个方法,所以我们在这里处理数据的时候,就会报错:循环引用。
            //EF生成的实体类,只是方便查询的,真正使用的时候,特别做序列化的时候,还是要转成我们自己的实体类,这种实体类,我们把他叫做DTO,我们在Model文件夹下,新建一个文件夹DTO,然后在里面继续添加类。。
            //备注: 拿到DTO集合之后,这边序列化的时候,就不会报错了。
            //此json方法,默认只允许Post请求
            return Json(jsonModel,JsonRequestBehavior.AllowGet);
          
        }
    }
}

Index视图的代码:

@{
    ViewBag.Title = "学员列表";
}
@section headSection{
    <script type="text/javascript">
        $(function () {
            //关闭Jquery的浏览器缓存
            //关闭缓存之后,每次都会发送一个数据到服务器获取数据
            $.ajaxSetup({ cache: false });
            //请求第一页数据
            LoadPageList(1);
        });
        //根据页码,异步请求数据
        //我们读取页面的数据,是在服务端读取数据之后,直接生成HTML代码发过来,显示在表格里面好?还是在服务端拿到数据之后,先把数据转成Json,发到浏览器,然后浏览器根据json数据转化为HTML代码好?
        //Josn好,Json的传输量小一点。
        //用json 的话就直接$.getJSON(),或者$.get()
        
        
        function LoadPageList(pageIndex)
        {
            //和getjson差不多,少了最后一个参数
            //$.get("Student/List" + pageIndex, null, function (jsonData) {
            //}, "json");
            //注意:get请求是不是使用浏览器缓存?那我们最好把浏览器缓存清除掉比较好。
            //技巧哦,可以使用一个全局的变量,把缓存关掉
            $.getJSON("Student/List" + pageIndex, null, function (jsonData) {
                alert(jsonData.msg);
            });
        }
    </script>
    
    
    }
<table id="tbList">
    <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Sex</th>
        <th>Age</th>
        <th>Class</th>
        <th>Operate</th>
    </tr>
</table>

然后就是每个DTO文件夹下的两个类的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MVCAjax01.Models.DTO
{
    /// <summary>
    /// DTO类的关键点是,我们自己写的类,而不是那个代理类,在用的时候,我们举找到查询的时候的代码,稍微修改一下
    /// 
    /// </summary>
    public class ClassDTO
    {
        //public Class()
        //{
        //    this.Students = new HashSet<Student>();
        //}
        public int c_ID { get; set; }
        public string c_Name { get; set; }
        //同理这个属性也稍作修改,去掉virtual,其实班级里面,我们不知道有没有学员,要知道的话,可以去查,所以这个属性去掉,这里就注释吧
        //public  ICollection<Student> Students { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MVCAjax01.Models.DTO
{
    ///DTO类的关键点是,我们自己写的类,而不是那个代理类,在用的时候,我们举找到查询的时候的代码,稍微修改一下
    /// <summary>
    /// 这里面的实体,和EF中的Student实体一样,直接copy过来。
    /// </summary>
    public class StudentDTO
    {
        public int s_ID { get; set; }
        public string s_Name { get; set; }
        public string s_Sex { get; set; }
        public Nullable<int> s_Age { get; set; }
        public int c_ID { get; set; }
        //只不过这个属性稍作修改
        public  ClassDTO Class { get; set; }
    }
}

DTO转化的方法类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MVCAjax01.Models
{
    /// <summary>
    /// 里面的名字要和EF一样,到时候合并为一个方法
    /// </summary>
    public partial class Student
    {
      #region  1.0版本  先不设置Claa属性
        //将EF Student实体,转成DTO学员实体
        //1.0版本  先不设置Claa属性
        //public DTO.Student ToDto()
        //{ 
        // return new DTO.Student()
        // {
        // s_ID=this.s_ID,
        // c_ID=this.c_ID,
        // s_Sex=this.s_Sex,
        // //Class=this.Class,  这里不能直接写,但这里可以不给,class是外键,需要的时候,查询的时候给。现在回到控制器
        // s_Age=this.s_Age,
        // s_Name=this.s_Name
         
        // };
          #endregion
        #region 2.0 版本设置Class属性
        public DTO.StudentDTO ToDto()
        {
            return new DTO.StudentDTO()
            {
                s_ID = this.s_ID,
                c_ID = this.c_ID,
                s_Sex = this.s_Sex,
                //Class=this.Class,  这里不能直接写,但这里可以不给,class是外键,需要的时候,查询的时候给。现在回到控制器
                s_Age = this.s_Age,
                s_Name = this.s_Name,
                Class = this.Class.ToDto()
            };
        #endregion
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MVCAjax01.Models
{
    /// <summary>
    /// 里面的名字要和EF一样,到时候合并为一个方法
    /// </summary>
    public partial class Class
    {
        public DTO.ClassDTO ToDto()
        {
            return new DTO.ClassDTO()
            {
                c_ID=this.c_ID,
                c_Name=this.c_Name
            };
        }
    }
}

分页数据实体类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MVCAjax01.Models
{
    //里面要添加的属性,就是刚才计算的。
    //写完之后,要序列化这个类。控制器中的操作:     //操作:将数据封装到PagedDataModel 分页数据实体中
    /// <summary>
    /// 分页数据实体
    /// </summary>
    public class PagedDataModel<T>
    {
        /// <summary>
        /// 数据
        /// </summary>
        public List<T> Data { get; set; }    //这个data属性,应该用object类型,当然也可以使用泛型,具体:把类写作泛型类,返回data属性弄成泛型
        /// <summary>
        /// 页码(在这里可以设置或者不设置)
        /// </summary>
        public int PageIndex { get; set; }
        /// <summary>
        /// 页容量(在这里可以设置或者不设置)
        /// </summary>
        public int PageSize { get; set; }
        
        /// <summary>
        /// 总页数
        /// </summary>
        public int PageCount { get; set; }
        /// <summary>
        /// 总行数(总数)
        /// </summary>
        public int RowCount { get; set; }
    }
}

JsonModel实体类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MVCAjax01.Models
{
    /// <summary>
    /// Json数据实体
    /// </summary>
    public class JsonModel
    {
        public object Data { get; set; }
        public string Message { get; set; }
        public string Status { get; set; }
        public string BackUrl { get; set; }
    }
}

最后附上几幅图:

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索数据
, 浏览器
, 代码
, this
, 属性
using
,以便于您获取更多的相关知识。

时间: 2024-10-25 11:31:45

Ajax请求asp.net MVC查出的列表数据转成DTO的实例的相关文章

ASP.NET Atlas ListView显示列表数据

asp.net|数据|显示 在目前的大部分Web程序中,我们都需要显示给用户一些列表数据.ASP.NET中的GridView服务器控件提供了这种功能,Atlas中的客户端控件ListView也可以在客户端提供类似功能,并以AJAX方式运行.虽然您可以使用传统的GridView控件加上Atlas的UpdatePanel提供同样的AJAX运行方式,但是这种实现方式较低效,也不是"纯粹"的Atlas方法.推荐的方法是采用Atlas的客户端控件ListView来代替.不要担心,Atlas的Li

Asp.net MVC 2.0 + Unity 2.0(IoC) + EF4.0 实例:RoRoWoBlog 开源项目框架代码

本开源项目当前使用框架如下: 前台表现:Asp.net MVC 2 数据持久层:ADO.Net Entity Framework 4.0 依赖注入容器:Unity 2.0 开发工具:VS2010   开源项目地址:http://rorowo.codeplex.com/   我这次国庆的时间  主要改了以下内容:1.改为POCO,使EF的实体纯净2.增加 IoCHelper类,把IoC的代码改为可以同时支持多种IoC3.修改基础结构层,使其可以支持多种ORM框架 4.修正继承自 DefaultCo

ASP.NET Mvc开发之查询数据_实用技巧

对于.NET平台上开发WebForm项目,程序员操作数据的方法主要是通过使用ADO.NET.而我们MVC操作数据库呢?与ADO.NET相比又有怎样的优势呢? 一.大家都在谈的EF到底是什么? EF,全称EntityFramWork.就是微软以ADO.NET为基础发展的所谓ORM(对象关系映射框架,或者说是数据持久化框架). 简单的来说就是根据实体对象操作数据表中数据的一种面向对象的操作框架,具体的底层也是调用ADO.NET. 下面我们就来演示怎么使用EF来操作数据库: 在数据库关系图中,表之间的

使用jQuery向asp.net Mvc传递复杂json数据-ModelBinder篇_jquery

调用jQuery的ajax方法时,jQuery会根据post或者get协议对参数data进行序列化; 如果提交的数据使用复杂的json数据,例如: {userId:32323,userName:{firstName:"李",lastName:"李大嘴"}} 那么服务器是无法正常接收到完整的参数,因为jQuery对data的序列化,是使用了键值对拼装的方式; 参数拼装成 userId=32323&userName=object ; userName所指向的对象

ASP.NET MVC 音乐商店 - 4. 数据访问

转自 http://www.cnblogs.com/haogj/archive/2011/11/13/2246884.html 上一次,我们使用了模拟的数据从控制器发送到视图模板.现在,我们开始使用真正的数据 库,在这个教程中,我们将指导如何使用 SQL Server Compact 版的数据库,它经常被称为 SQL CE, 来作为数据库引擎,SQL CE 是一个免费的,嵌入式的,基于文件的数据库系统,不需要任何的安装或者配置,很适合本地的开发使用. 注意:可能需要单独安装 SQL Server

ASP.NET MVC中在路由表routes集合中添加Route实例的问题

昨天有位同学问到关于在routes集合中添加自定义的路由实例的问题,她出现的问题是这样的: 1.因为要在应用程序戾动时将实例添加到routes表中,所以需要把代码写在Global类的RegisterRoutes方法中,代码如下两种方式:    routes.Add("s", new Route("a/b", new WebFormRouteHandler("~/WebForm1.aspx")));    routes.Add("a&qu

Asp.net MVC 4 模型的数据注释

[Bind(-)] Lists fields to exclude or include when binding parameter or form values to model properties 列表字段时,排除或包括绑定参数或表单模型属性值 [Compare("-")] To compare two properties. 对比两个属性. [CreditCard] To Specify that a data field value is a credit card num

Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 3 ----数据访问层

在上一篇中,我们已经搭建起了整个解决方案的项目,并且建好了数据库,完成了实体类和Nhibernate映射文件.在本文中,将定义数据访问接口,并利用Nhibernate实现接口,利用Spring.net配置起来dao.并对其进行单元测试. 数据访问层也和Petshop等框架一样,分为数据访问的接口以及实现,不过这里的数据访问实现相比之下就清晰和明显了的多,Nhibernate本身就是支持多数据库的,所以这样做不是为了多数据库,而是为了Nhibernate的可插拨,即使哪一天发现由于一些问题,比如说

Asp.Net MVC 把PartialView、View转换成字符串

1,输出View HTML 字符串:    代码如下 复制代码 /// <summary> /// 描述:输出View HTML 字符串 /// </summary> /// <param name="controller"></param> /// <param name="viewName">视图文件名</param> /// <param name="masterName&