首页 > 代码库 > MVC - 11.DTO

MVC - 11.DTO

1.重要:javaScriptSerializer 无法识别被序列化的对象里各种属性是否存在  循环依赖

(System,Web.Script.Serialization.JavaScriptSerializer)

所以,我们不能使用javaScriptSerializer 去序列化 EF 实体对象A 。

因为javaScriptSerializer 会循环 EF 实体对象 A 里的每个属性,想要根据此属性生成对应的Json字符串,但是,EF 实体A 的外键(导航)属性如果被访问,则自动去数据库获取,而这个导航属性对应的实体类 B 中可能又包含指向实体 A 的类型,那么,EF又会去加载 A 的数据,然后 A里又包含B。。。。。陷入死循环。。。

(参考2013-5-31-mvc)

image

 

2.后台如果取数据需要转换成json发送到前台如图,Class就不能获取数据。所以我们需要采用DTO

image

 

 

2.1.前台ajax请求Student数据

Stu/Index.cshtml

 

2.2.后台获取数据

//根据页码加载数据 此方法的Id其实是页码        public ActionResult List(int id)        {            //页码            int pageIndex = id;            //页容量            int pageSize = 2;            //2.1 根据页码获取分页数据            List<Models.Student> list = db.Students.Include("Class").OrderBy(s => s.StudentID)                .Take(pageSize).Skip((pageIndex - 1) * pageSize).ToList();            //2.2 获取总行数            int rowCount = db.Students.Count();            //2.3 计算总页数            int pageCount = Convert.ToInt32(Math.Ceiling((rowCount*1.0)/pageSize));                        return null;        }

 

3.这个时候我们来创建DTO

image

 

注意:

1.去掉virtual

public virtual Class Class { get; set; }

2.//public class Class{...} //报错
    //这里ClassDTO.cs不能是用Class.cs同名类,因为EF不认识,会报下列错误
    //CLR到EDM的类型映射不明确,因为多个CLR类型与EDM类型“Class”匹配,

image

 

StudentDTO.cs

using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace _06MVCAjax_CodeFirst.Models.DTO{    //public class Student{...} //报错    //这里StudentDTO.cs不能是用Student.cs同名类,因为EF不认识,会报下列错误    //CLR到EDM的类型映射不明确,因为多个CLR类型与EDM类型“Student”匹配,    public class StudentDTO    {        public int StudentID { get; set; }        public Nullable<int> Cid { get; set; }        public string Name { get; set; }        public string Gender { get; set; }        public Nullable<int> Isdel { get; set; }        public Nullable<System.DateTime> AddTime { get; set; }                //注意这里是ClassDTO类型        public ClassDTO Class { get; set; }    }}

 

ClassDTO.cs

using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace _06MVCAjax_CodeFirst.Models.DTO{    //public class Class{...} //报错    //这里ClassDTO.cs不能是用Class.cs同名类,因为EF不认识,会报下列错误    //CLR到EDM的类型映射不明确,因为多个CLR类型与EDM类型“Class”匹配,    public class ClassDTO    {        public ClassDTO()        {            this.Students = new List<Student>();        }        public int Cid { get; set; }        public string CName { get; set; }        public Nullable<int> CCount { get; set; }        public string CImg { get; set; }        public string CIsdel { get; set; }        public Nullable<System.DateTime> Addtime { get; set; }        public  ICollection<Student> Students { get; set; }    }}

 

4.将EF查询出来的 EF实体集合 转换成 Dto(Data Transfer Object)数据传输类型

List<Models.DTO.StudentDTO> list = db.Students.Include("Class").OrderBy(s => s.StudentID)                .Take(pageSize).Skip((pageIndex - 1) * pageSize).ToList()                .Select(s => new Models.DTO.StudentDTO() {StudentID=s.StudentID,Cid=s.Cid}).ToList(); //将EF查询出来的 EF实体集合 转换成 Dto(Data Transfer Object)数据传输类型

 

4.1.Select(s => new Models.DTO.StudentDTO() {StudentID=s.StudentID,Cid=s.Cid}).ToList();

//将EF查询出来的 EF实体集合 转换成 Dto(Data Transfer Object)数据传输类型

如果自己在类里面写个方法,把它转换为DTO,就不用每次写一样的这么麻烦了。所以我们在Models文件夹添加一个类

注意:

1.partial class Class

2.ClassPart.cs 返回类型是DTO.ClassDTO

3.StudentPart.cs 里面 Class = this.Class.ToDto()

这里要注意的是 StudentDTO.cs 类文件里面的 public ClassDTO Class { get; set; }

不然会报错,无法将类型“_06MVCAjax_CodeFirst.Models.DTO.ClassDTO”隐式转换为“_06MVCAjax_CodeFirst.Models.Class”

ClassPart.cs

using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace _06MVCAjax_CodeFirst.Models{    public partial class Class    {        /// <summary>        /// 将 ED的班级对象转成 DTO 的班级对象        /// </summary>        /// <returns></returns>        public DTO.ClassDTO ToDto()        {            return new DTO.ClassDTO()            {                Cid = this.Cid,                CName = this.CName,                CCount = this.CCount,                CImg = this.CImg,                CIsdel = this.CIsdel,                Addtime = this.Addtime            };        }    }}

 

StudentPart.cs

using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace _06MVCAjax_CodeFirst.Models{        public partial class Student    {        /// <summary>        /// 将 EF Student实体转换成 DTO 学员实体        /// </summary>        public DTO.StudentDTO ToDto()        {            return new DTO.StudentDTO()            {                StudentID = this.StudentID,                Cid = this.Cid,                Name = this.Name,                Gender = this.Gender,                Isdel = this.Isdel,                AddTime = this.AddTime,                Class = this.Class.ToDto()            };        }    }}

 

5.将数据封装到 PagedDataModel 实体

写个类PagedDataModel<T>

 

PagedDataModel.cs

using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace _06MVCAjax_CodeFirst.Models{    /// <summary>    /// 分页数据实体    /// </summary>    public class PagedDataModel<T>    {        /// <summary>        /// 封装数据        /// </summary>        public List<T> PageData { get; set; }        /// <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; }    }}

 

6.将分页数据实体 封装到 json标准格式实体中

JsonModel.cs

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

 

7.最后的控制器里的List方法

StuController.cs

using System;using System.Collections.Generic;using System.Data;using System.Linq;using System.Web;using System.Web.Mvc;namespace _06MVCAjax_CodeFirst.Controllers{    public class StuController : Controller    {        //        // GET: /Stu/        private Models.SingleTestContext db = new Models.SingleTestContext();        public ActionResult Index()        {            return View();        }        //根据页码加载数据 此方法的Id其实是页码        public ActionResult List(int id)        {            //页码            int pageIndex = id;            //页容量            int pageSize = 2;            //2.1 根据页码获取分页数据            List<Models.DTO.StudentDTO> list = db.Students.Include("Class").OrderBy(s => s.StudentID)                .Take(pageSize).Skip((pageIndex - 1) * pageSize).ToList()                .Select(s => s.ToDto()).ToList(); //将EF查询出来的 EF实体集合 转换成 Dto(Data Transfer Object)数据传输类型            //2.2 获取总行数            int rowCount = db.Students.Count();            //2.3 计算总页数            int pageCount = Convert.ToInt32(Math.Ceiling((rowCount * 1.0) / pageSize));            //2.4 将数据封装到 PagedDataModel 实体            Models.PagedDataModel<Models.DTO.StudentDTO> dataModel = new Models.PagedDataModel<Models.DTO.StudentDTO>()                                                                {                                                                    PageData = list,                                                                    PageCount = pageCount,                                                                    PageIndex = pageIndex,                                                                    PageSize = pageSize                                                                };            //2.5 将分页数据实体 封装到 json标准格式实体中            Models.JsonModel jsonModel = new Models.JsonModel()                                             {                                                 Data = dataModel,                                                 Msg = "成功",                                                 Statu = "OK"                                             };            //System.Web.Script.Serialization.JavaScriptSerializer js = new System.Web.Script.Serialization.JavaScriptSerializer();            //string x = js.Serialize(jsonModel);            //2.6 生成json 格式数据,Json方法是Controller类(控制器类)提供的            //JsonRequestBehavior.AllowGet 一般啊只使用post传输,如果使用get,需要设置AllowGet            return Json(jsonModel, JsonRequestBehavior.AllowGet);        }    }}

 

string x = js.Serialize(jsonModel);

image

 

 

8.错误

8.1.get请求报错

 image

//2.6 生成json 格式数据,Json方法是Controller类(控制器类)提供的

//JsonRequestBehavior.AllowGet 一般啊只使用post传输,如果使用get,需要设置AllowGet

return Json(jsonModel, JsonRequestBehavior.AllowGet);

8.2.查询的时候没加ToList(),不识别ToDto()方法

image

image