【SubSonic 2.2】用于 WebService 时存在的性能危机

09年我用 Silverlight 2 + WebService(还不是 WCF)做的项目,今天突然接到客户的反馈,说是某个项目的数据显示出不来,但是另一个项目的数据又很正常,而且这两个项目的数据基本上没什么太大的区别。

 

故障现象

  1. Web 端抛出 System.OutOfMemoryException。
  2. 有的数据从 Web 端到 Silverlight 客户端的传输极慢,有的数据却速度飞快。

故障分析

  1. 故障所涉及的数据库表主要有两张:
    表A:AId(主键,GUID)、BId(表B的外键,GUID,可以为空)
    表B:BId(主键,GUID)、BImage(Image,非空)
    数据访问使用了 SubSonic 2.2。
  2. WebService 方法大致是这样的:
    List<A> GetAs()
    {
        ACollection as = new ACollection().......Load();
    }
    没有办法再简单了。。。
  3. 在 Silverlight 客户端和 Web 端都加了断点,发现故障主要是在 Web Service 的方法调用之后,客户端接收之前发生的。
    在这个过程中,并不执行任何自定义的代码,除了框架自动生成的 XML 序列化功能。
  4. 经过反复对比,出问题的数据有一个特点,即表A中的记录的 BId 字段都不为空。
    能够造成 OutOfMemory 以及大数据量的不就是图片数据吗,不得不怀疑,是不是图片数据也一起被 Web 端序列化了。
  5. 查看表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  阅读(938)  评论(0编辑  收藏  举报