`
GaryChen
  • 浏览: 7532 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

WCF和Entity framework 发现的性能问题

    博客分类:
  • EF
阅读更多

 

最近在用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类代码

 

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

 

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

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics