【SubSonic 2.2】用于 WebService 时存在的性能危机
09年我用 Silverlight 2 + WebService(还不是 WCF)做的项目,今天突然接到客户的反馈,说是某个项目的数据显示出不来,但是另一个项目的数据又很正常,而且这两个项目的数据基本上没什么太大的区别。
故障现象
- Web 端抛出 System.OutOfMemoryException。
- 有的数据从 Web 端到 Silverlight 客户端的传输极慢,有的数据却速度飞快。
故障分析
- 故障所涉及的数据库表主要有两张:
表A:AId(主键,GUID)、BId(表B的外键,GUID,可以为空)
表B:BId(主键,GUID)、BImage(Image,非空)
数据访问使用了 SubSonic 2.2。 - WebService 方法大致是这样的:
List<A> GetAs()
{
ACollection as = new ACollection().......Load();
}
没有办法再简单了。。。 - 在 Silverlight 客户端和 Web 端都加了断点,发现故障主要是在 Web Service 的方法调用之后,客户端接收之前发生的。
在这个过程中,并不执行任何自定义的代码,除了框架自动生成的 XML 序列化功能。 - 经过反复对比,出问题的数据有一个特点,即表A中的记录的 BId 字段都不为空。
能够造成 OutOfMemory 以及大数据量的不就是图片数据吗,不得不怀疑,是不是图片数据也一起被 Web 端序列化了。 - 查看表A生成的 ORM 代码,发现外键对象的定义是这样的:
public B B
{
get { return B.FetchByID(this.BId);
set { SetColumnValue("BId", value.BId);
}
这样就明了了,WebService 在序列化 A 对象时,访问了 B 属性,get B 属性时去数据库获取了 B 对象,其中包含了图片数据。
解决方法
- 在 WebService 方法中,把 A 集合中的每个元素的 Bid 属性都置为 Null,这个是应急的办法,虽然速度快,但是数据被阉割了。
- 在表A对应的 ORM 类定义中,给 B 属性添加标签:
[System.Xml.Serialization.XmlIgnore]
这个是比较常规的做法,不序列化外键对象 B,同时在客户端屏蔽了对外键对象 B 的调用。
posted on 2010-12-08 16:24 CsharpStyle 阅读(939) 评论(0) 编辑 收藏 举报