最近在用entity framework 和 WCF结合做服务端,偶然发现一个问题,就是数据传输对象(DTO)的容量问题,我的项目方案是把数据访问层封装为WCF部署在外网服务器上供客户端调用.我发现传输速度没有想象的那么好,简直就是不堪入目,终于有一天我发现问题的所在,就是edmx生成的实体类和自己手写实体类的区别,我用District这张表来做演示,表中一共有5个字段,废话不多说,先看一代码,
下面是edmx自生成的District类代码
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->[global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="ExpressPlatformModel", Name="District")]
[global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
[global::System.Serializable()]
public partial class District : global::System.Data.Objects.DataClasses.EntityObject
{
/// <summary>
/// 创建新的 District 对象。
/// </summary>
/// <param name="districtID">DistrictID 的初始值。</param>
/// <param name="cityID">CityID 的初始值。</param>
/// <param name="districtName">DistrictName 的初始值。</param>
public static District CreateDistrict(int districtID, int cityID, string districtName)
{
District district = new District();
district.DistrictID = districtID;
district.CityID = cityID;
district.DistrictName = districtName;
return district;
}
/// <summary>
/// 架构中不存在属性 DistrictID 的注释。
/// </summary>
[global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
[global::System.Runtime.Serialization.DataMemberAttribute()]
public int DistrictID
{
get
{
return this._DistrictID;
}
set
{
this.OnDistrictIDChanging(value);
this.ReportPropertyChanging("DistrictID");
this._DistrictID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
this.ReportPropertyChanged("DistrictID");
this.OnDistrictIDChanged();
}
}
private int _DistrictID;
partial void OnDistrictIDChanging(int value);
partial void OnDistrictIDChanged();
/// <summary>
/// 架构中不存在属性 CityID 的注释。
/// </summary>
[global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
[global::System.Runtime.Serialization.DataMemberAttribute()]
public int CityID
{
get
{
return this._CityID;
}
set
{
this.OnCityIDChanging(value);
this.ReportPropertyChanging("CityID");
this._CityID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
this.ReportPropertyChanged("CityID");
this.OnCityIDChanged();
}
}
private int _CityID;
partial void OnCityIDChanging(int value);
partial void OnCityIDChanged();
/// <summary>
/// 架构中不存在属性 DistrictName 的注释。
/// </summary>
[global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
[global::System.Runtime.Serialization.DataMemberAttribute()]
public string DistrictName
{
get
{
return this._DistrictName;
}
set
{
this.OnDistrictNameChanging(value);
this.ReportPropertyChanging("DistrictName");
this._DistrictName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
this.ReportPropertyChanged("DistrictName");
this.OnDistrictNameChanged();
}
}
private string _DistrictName;
partial void OnDistrictNameChanging(string value);
partial void OnDistrictNameChanged();
/// <summary>
/// 架构中不存在属性 PinYin 的注释。
/// </summary>
[global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
[global::System.Runtime.Serialization.DataMemberAttribute()]
public string PinYin
{
get
{
return this._PinYin;
}
set
{
this.OnPinYinChanging(value);
this.ReportPropertyChanging("PinYin");
this._PinYin = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
this.ReportPropertyChanged("PinYin");
this.OnPinYinChanged();
}
}
private string _PinYin;
partial void OnPinYinChanging(string value);
partial void OnPinYinChanged();
/// <summary>
/// 架构中不存在属性 PostalCode 的注释。
/// </summary>
[global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
[global::System.Runtime.Serialization.DataMemberAttribute()]
public string PostalCode
{
get
{
return this._PostalCode;
}
set
{
this.OnPostalCodeChanging(value);
this.ReportPropertyChanging("PostalCode");
this._PostalCode = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
this.ReportPropertyChanged("PostalCode");
this.OnPostalCodeChanged();
}
}
private string _PostalCode;
partial void OnPostalCodeChanging(string value);
partial void OnPostalCodeChanged();
}
这是我手写的District类
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> [DataContract]
[Serializable]
public class SDistrict
{
public SDistrict() { }
[DataMember]
private int districtID = 0;
public int DistrictID
{
get { return districtID; }
set { districtID = value; }
}
[DataMember]
private int cityID = 0;
public int CityID
{
get { return cityID; }
set { cityID = value; }
}
[DataMember]
private string districtName = string.Empty;
public string DistrictName
{
get { return districtName; }
set { districtName = value; }
}
[DataMember]
private string pinYin = string.Empty;
public string PinYin
{
get { return pinYin; }
set { pinYin = value; }
}
[DataMember]
private string postalCode = string.Empty;
public string PostalCode
{
get { return postalCode; }
set { postalCode = value; }
}
}
大家都看见了,edmx生成的和手写的District结构都是一模一样的,同样都有DataContract这个类属性,可以序列化和反序列化.下面是我Service中返回不同实体集合的一段代码,
自定义District类获取方法
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> public List<SDistrict> initBuffByDistrict() //自己手写的实体类
{
using (ExpressPlatformEntities db = new ExpressPlatformEntities())
{
List<District> result = db.District.ToList<District>();
List<SDistrict> result1 = new List<SDistrict>(result.Count);
for (int i = 0; i < result.Count; i++)
{
SDistrict sd = new SDistrict();
sd.DistrictID = result[i].DistrictID;
sd.DistrictName = result[i].DistrictName;
sd.CityID = result[i].CityID;
sd.PinYin = result[i].PinYin;
sd.PostalCode = result[i].PostalCode;
result1.Add(sd);
}
return result1;
}
edmx生成的District类获取方法
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> public List<District> GetDistrictList()
{
using (ExpressPlatformEntities db = new ExpressPlatformEntities())
{
return db.District.ToList();
}
}
客户端使用http协议调用这两个方法的结果我用Fiddler测试工具抓取响应的消息所获得才恍 <script type="text/javascript"></script><script type="text/javascript"></script><script type="text/javascript"></script><script type="text/javascript"></script> 然大悟啊,请看下面
测试返回省市区表对象3304,以下是用entity framework 自生成的实体集合
==================================================================
Request Count: 1 //请求数
Bytes Sent: 1,090//发送字节数
Bytes Received: 2,462,366 //接收字节数
ACTUAL PERFORMANCE
--------------
Requests started at: 10:24:09:1406 //请求开始
Responses completed at: 10:24:17:5781 //响应返回
Aggregate Session time: 00:00:08:4375 //耗时
Sequence (clock) time: 00:00:08.4375000 //总耗时
测试返回省市区表对象3304,以下是用手写的实体集合
===============================================
Request Count: 1//请求数
Bytes Sent: 1,088//发送字节
Bytes Received: 634,171//接收字节
ACTUAL PERFORMANCE
--------------
Requests started at: 10:16:07:2500//请求开始
Responses completed at: 10:16:09:5625//响应返回
Aggregate Session time: 00:00:02:3125//耗时
Sequence (clock) time: 00:00:02.3125000//总耗时
===================华丽的分割线========================================
相差了6秒多,而且字节数相差了4倍左右,3304个实体的数据总量一共是600K左右,传600K数据需要8秒?
我把这两个集合序列化到文本一看,一个edmx生成的实体类集合有2.33MB的容量,手写的实体集合只有610K,实际上手写的
实体集合序列化为Soap-XML进行传输的时候那些声明数据的类型的XML节点只占用了10K的大小,而通过edmx生成的
Soap-XML包含了edmx的许多属性,这样就能得出为什么手写的比生成的快了.
文章到这里结束了,希望能给大家提供帮助,也欢迎大牛和同行拍砖指点和纠正
相关推荐
asp.net+wcf+entity framework
EasyUI ajax for WCF和Entity FrameWork4
wcf,entityframework,mef,mvc框架源码含仓储模式
WCF+Silverlight+EntityFramework+Sqlite所做的学生信息管理系统,自己闲暇时间做着玩的,页面什么的比较丑,不过不要在意那些细节……数据库采用Sqlite,非常小的一个数据库,我就不提供了,网上一大堆,表结构什么...
Entity Framework 已经发布多时,但是要在不同的环境中构建基于其上的应用程序还是需要很多考量的。本文介绍了如何在WCF环境下使用EF,并对如何在其中进行并发控制做出了讨论。其中还包括了相应的代码示例。本文件...
Title: WCF Multi-Layer Services Development with Entity Framework, 4th Edition Author: Mike Liu Length: 388 pages Edition: 4 Language: English Publisher: Packt Publishing Publication Date: 2014-10-27 ...
This book is a step-by-step tutorial to guide you through learning WCF, Entity Framework, LINQ, and LINQ to Entities. You will be guided to create six WCF and Entity Framework solutions from scratch, ...
EntityFramework+仓储模式实现的WCF分布式服务,可接任意的数据库!
It will also teach you how you can work with RESTful Services and Google's Protocol Buffers with Entity Framework and WCF. You will explore how to use Entity Framework with ASP.NET Web API and also ...
Written by JuliaLerman, the leading independent authority on the framework,Programming Entity Framework covers it all -- from the Entity DataModel and Object Services to WCF Services, MVC Apps, and ...
Chapter 1: Introducing the ADO.NET 4.0 Entity Framework..................................1 Chapter 2: The Entity Data Model ........................................................13 Chapter 3: The ...
基于spring.net EntityFramework 实现WCF服务层,有MVC测试等等,后面就是为了凑数了
[Packt Publishing] WCF 4.5 多层服务开发 —— 使用 Entity Framework 技术 第3版 [Packt Publishing] WCF 4.5 Multi-Layer Services Development with Entity Framework 3rd Edition (E-Book) ☆ 出版信息:☆ ...
Ado.Net Entity Framework+WCF的一个Demo
WCF+Silverlight+EntityFramework+Sqlite所做的学生信息管理系统
Written by Julia Lerman, the leading independent authority on the framework, Programming Entity Framework covers it all - from the Entity Data Model and Object Services to WCF Services, MVC Apps, and...
EntityFramework仓储模式实现的WCF分布式服务!支持多种数据库
Using Entities with Web and WCF Services, Using the Entity Framework in n-Tier ASP.NET Applications and n-Tier Client-Side Applications, Handling Entity Framework Exceptions, Performance, Security, ...
Entity Framework的全称是ADO.NET Entity Framework,是微软开发的基于ADO.NET的ORM(Object/Relational Mapping)框架。 Entity Framework的主要特点: 1. 支持多种数据库(Microsoft SQL Server, Oracle, and DB2)...