wcF2

来源:互联网 发布:听见下雨的声音 知乎 编辑:程序博客网 时间:2024/04/29 03:02

最近在用entity framework 和 WCF结合做服务端,偶然发现一个问题,就是数据传输对象(DTO)的容量问题,我的项目方案是把数据访问层封装为WCF部署在外网服务器上供客户端调 用.我发现传输速度没有想象的那么好,简直就是不堪入目,终于有一天我发现问题的所在,就是edmx生成的实体类和自己手写实体类的区别,我用 District这张表来做演示,表中一共有5个字段,废话不多说,先看一代码,
下面是edmx自生成的District类代码

复制代码
  1 代码  2   3 [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="ExpressPlatformModel", Name="District")]  4     [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]  5     [global::System.Serializable()]  6     public partial class District : global::System.Data.Objects.DataClasses.EntityObject  7     {  8         /// <summary>  9         /// 创建新的 District 对象。 10         /// </summary> 11         /// <param name="districtID">DistrictID 的初始值。</param> 12         /// <param name="cityID">CityID 的初始值。</param> 13         /// <param name="districtName">DistrictName 的初始值。</param> 14         public static District CreateDistrict(int districtID, int cityID, string districtName) 15         { 16             District district = new District(); 17             district.DistrictID = districtID; 18             district.CityID = cityID; 19             district.DistrictName = districtName; 20             return district; 21         } 22         /// <summary> 23         /// 架构中不存在属性 DistrictID 的注释。 24         /// </summary> 25         [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] 26         [global::System.Runtime.Serialization.DataMemberAttribute()] 27         public int DistrictID 28         { 29             get 30             { 31                 return this._DistrictID; 32             } 33             set 34             { 35                 this.OnDistrictIDChanging(value); 36                 this.ReportPropertyChanging("DistrictID"); 37                 this._DistrictID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); 38                 this.ReportPropertyChanged("DistrictID"); 39                 this.OnDistrictIDChanged(); 40             } 41         } 42         private int _DistrictID; 43         partial void OnDistrictIDChanging(int value); 44         partial void OnDistrictIDChanged(); 45         /// <summary> 46         /// 架构中不存在属性 CityID 的注释。 47         /// </summary> 48         [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] 49         [global::System.Runtime.Serialization.DataMemberAttribute()] 50         public int CityID 51         { 52             get 53             { 54                 return this._CityID; 55             } 56             set 57             { 58                 this.OnCityIDChanging(value); 59                 this.ReportPropertyChanging("CityID"); 60                 this._CityID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); 61                 this.ReportPropertyChanged("CityID"); 62                 this.OnCityIDChanged(); 63             } 64         } 65         private int _CityID; 66         partial void OnCityIDChanging(int value); 67         partial void OnCityIDChanged(); 68         /// <summary> 69         /// 架构中不存在属性 DistrictName 的注释。 70         /// </summary> 71         [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] 72         [global::System.Runtime.Serialization.DataMemberAttribute()] 73         public string DistrictName 74         { 75             get 76             { 77                 return this._DistrictName; 78             } 79             set 80             { 81                 this.OnDistrictNameChanging(value); 82                 this.ReportPropertyChanging("DistrictName"); 83                 this._DistrictName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false); 84                 this.ReportPropertyChanged("DistrictName"); 85                 this.OnDistrictNameChanged(); 86             } 87         } 88         private string _DistrictName; 89         partial void OnDistrictNameChanging(string value); 90         partial void OnDistrictNameChanged(); 91         /// <summary> 92         /// 架构中不存在属性 PinYin 的注释。 93         /// </summary> 94         [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] 95         [global::System.Runtime.Serialization.DataMemberAttribute()] 96         public string PinYin 97         { 98             get 99             {100                 return this._PinYin;101             }102             set103             {104                 this.OnPinYinChanging(value);105                 this.ReportPropertyChanging("PinYin");106                 this._PinYin = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);107                 this.ReportPropertyChanged("PinYin");108                 this.OnPinYinChanged();109             }110         }111         private string _PinYin;112         partial void OnPinYinChanging(string value);113         partial void OnPinYinChanged();114         /// <summary>115         /// 架构中不存在属性 PostalCode 的注释。116         /// </summary>117         [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]118         [global::System.Runtime.Serialization.DataMemberAttribute()]119         public string PostalCode120         {121             get122             {123                 return this._PostalCode;124             }125             set126             {127                 this.OnPostalCodeChanging(value);128                 this.ReportPropertyChanging("PostalCode");129                 this._PostalCode = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);130                 this.ReportPropertyChanged("PostalCode");131                 this.OnPostalCodeChanged();132             }133         }134         private string _PostalCode;135         partial void OnPostalCodeChanging(string value);136         partial void OnPostalCodeChanged();137     }
复制代码


这是我手写的District类

复制代码
 1 代码 2  3   [DataContract] 4         [Serializable] 5         public class SDistrict 6         { 7             public SDistrict() { } 8             [DataMember] 9             private int districtID = 0;10 11             public int DistrictID12             {13                 get { return districtID; }14                 set { districtID = value; }15             }16             [DataMember]17             private int cityID = 0;18 19             public int CityID20             {21                 get { return cityID; }22                 set { cityID = value; }23             }24             [DataMember]25             private string districtName = string.Empty;26 27             public string DistrictName28             {29                 get { return districtName; }30                 set { districtName = value; }31             }32             [DataMember]33             private string pinYin = string.Empty;34 35             public string PinYin36             {37                 get { return pinYin; }38                 set { pinYin = value; }39             }40             [DataMember]41             private string postalCode = string.Empty;42 43             public string PostalCode44             {45                 get { return postalCode; }46                 set { postalCode = value; }47             }48 49         }
复制代码


大家都看见了,edmx生成的和手写的District结构都是一模一样的,同样都有DataContract这个类属性,可以序列化和反序列化.下面是我Service中返回不同实体集合的一段代码,

自定义District类获取方法

复制代码
 1 代码 2  3   public List<SDistrict> initBuffByDistrict() //自己手写的实体类 4         { 5              6             using (ExpressPlatformEntities db = new ExpressPlatformEntities()) 7             { 8  9                 List<District> result = db.District.ToList<District>();10                 List<SDistrict> result1 = new List<SDistrict>(result.Count);11                 for (int i = 0; i < result.Count; i++)12                 {13                     SDistrict sd = new SDistrict();14                     sd.DistrictID = result[i].DistrictID;15                     sd.DistrictName = result[i].DistrictName;16                     sd.CityID = result[i].CityID;17                     sd.PinYin = result[i].PinYin;18                     sd.PostalCode = result[i].PostalCode;19                     result1.Add(sd);20                 }21               22                23                24                 return result1;25             }
复制代码

edmx生成的District类获取方法

复制代码
1 代码2 3         public List<District> GetDistrictList()4         {5             using (ExpressPlatformEntities db = new ExpressPlatformEntities())6             {7                 return db.District.ToList();8             }9         }
复制代码

 

客户端使用http协议调用这两个方法的结果我用Fiddler测试工具抓取响应的消息所获得才恍 然大悟啊,请看下面

测试返回省市区表对象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的许多属性,这样就能得出为什么手写的比生成的快了.

原创粉丝点击