WCF和Entity framework 发现的性能问题

 

最近在用entity framework 和 WCF结合做服务端,偶然发现一个问题,就是数据传输对象(DTO)的容量问题,我的项目方案是把数据访问层封装为WCF部署在外网服务器上供客户端调用.我发现传输速度没有想象的那么好,简直就是不堪入目,终于有一天我发现问题的所在,就是edmx生成的实体类和自己手写实体类的区别,我用District这张表来做演示,表中一共有5个字段,废话不多说,先看一代码,
下面是edmx自生成的District类
代码
这是我手写的District类
代码
大家都看见了,edmx生成的和手写的District结构都是一模一样的,同样都有DataContract这个类属性,可以序列化和反序列化.下面是我Service中返回不同实体集合的一段代码,
自定义District类获取方法
代码
edmx生成的District类获取方法
代码
客户端使用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//总耗时
测试返回省市区表对象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的许多属性,这样就能得出为什么手写的比生成的快了.
文章到这里结束了,希望能给大家提供帮助,也欢迎大牛和同行拍砖指点和纠正

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

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
  
<!--<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类

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
  
<!--<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类获取方法

 

 

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
  
<!--<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类获取方法

 

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
  
<!--<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的许多属性,这样就能得出为什么手写的比生成的快了.

 

文章到这里结束了,希望能给大家提供帮助,也欢迎大牛和同行拍砖指点和纠正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值