silverlight+wcf:relation entity VS. relation entity's code
2010-04-07 04:59 Virus-BeautyCode 阅读(1599) 评论(2) 编辑 收藏 举报本文主要探讨一下,在使用silverlight+wcf进行数据库操作的时候,且约定的交互标准是实体的前提下,在实体中是该使用关系实体的编号作为属性呢?还是将关系实体整体作为属性呢?
举个例子来说:两个实体,一个是person,用户信息,一个是District地域信息,暂时只考虑中国的5级地域层级,district和person是一个典型的0-1:N关系,在N的一端加入0-1一端的编号作为一个字段来存储,下面是用工具生成的数据库实体
public class Person
{
private int _code;
[DataMember]
public int Code {
get { return _code; }
set { _code = value; }
}
private string _name;
[DataMember]
public string Name {
get { return _name; }
set { _name = value; }
}
private int _disCode;
[DataMember]
public int DisCode {
get { return _classCode; }
set { _classCode = value; }
}
}
[DataContract]
public class District
{
private int _code;
[DataMember]
public int Code {
get { return _code; }
set { _code = value; }
}
private int _parentCode;
[DataMember]
public int ParentCode {
get { return _parentCode; }
set { _parentCode = value; }
}
private string _name;
[DataMember]
public string Name {
get { return _name; }
set { _name = value; }
}
}
生成之后,我们可能需要对实体进行调整,因为自动生成的肯定和我们的业务关系不大,它只能原始的反映数据库的结构,帮我们减少一些体力劳动,切忌,一定要修改,出来混迟早要还的。
我们就像把关系属性的code,改成关系实体本身,修改如下
public class Person
{
private int _code;
[DataMember]
public int Code {
get { return _code; }
set { _code = value; }
}
private string _name;
[DataMember]
public string Name {
get { return _name; }
set { _name = value; }
}
private District _district;
[DataMember]
public District District {
get { return _district; }
set { _district = value; }
}
}
[DataContract]
public class District
{
private int _code;
[DataMember]
public int Code {
get { return _code; }
set { _code = value; }
}
private District _parent;
[DataMember]
public District Parent {
get { return _parent; }
set { _parent = value; }
}
private string _name;
[DataMember]
public string Name {
get { return _name; }
set { _name = value; }
}
}
比较明显的就是关系,原来都是使用code,现在都换成关系本身了,包括原来是parentcode的属性,也换成parent,类型从int变成了district,看起来很好理解了,而且很容易的想到应该可以增加的好处,使用person.District就可以知道一个人所在地域的名称,要不然光有编号,还需要用编号来查询名称,甚至说显示的时候,不能只显示person的第五级地域信息,也就是不能光显示人员在那个村子,要显示完整的省-市-县-乡-村,这个时候如果地域中由一个District类型的parent就比由一个int类型的parentCode要好用的多。
因为silverlight是RIA应用,而且在客户端还是有一个运行环境的,虽然运行在浏览器中,但是还是有点类似C/S结构的,只是受到一些限制,同时有自己的一些运行机制。不能直接访问数据库,只能依赖一些服务性的接口来完成数据库交互。wcf是一种可选的方案,wcf交互的标准是SOA,数据都是被序列化成xml,使用wcf之后,往返于client和server端的数据会被序列化,可以使用wcf特有的DataContract和DataMember来标记需要序列化的数据,在上面的实体类中我们已经加上标记。
加入标记的数据在服务器端就会被反序列化成服务器实体,传输的时候又要将加入标记的数据序列化成xml,在客户端接收数据之后,又会将加上标记的属性反序列化成客户端实体,因为每次要传输数据在客户端的运行时中运行,这就需要我们设计的实体类要减少传输的量,减少传输的数据冗余。
就拿前面类来说把,如果现在有一个addperson的功能,其实数据库需要的就是一个districtcode就可以保存了,不需要知道disrictname和其他的信息,所以在person中的属性districtcode还不能完全由int改成district类型的district,要不让会多序列化一些name和district的其他属性,如果district有了parent和child的话,那就不止多一两个了,就是说这时候还是用int的districtcode就可以满足要求了,至少需要保留两个属性,一个int的districtcode,一个是district的district,一个用在保存用户的时候,districtcode赋值,district=null;。
很多时候,很多实体,像我们原来开发ASP.NET的话,关系实体的code,都会被修改成关系实体本身,其实在silverlight中,或者说在客户端有运行环境的情况下,其实一个code就可以了,因为
1)其他的信息客户端可能早就从服务器获取了,例如code和name的对应关系,因为不像ASP.NET是无状态的,客户端看到的都是html,再丰富的页面到了客户端也都是html+JavaScript,类似silverlight这种RIA的话,客户端有点像C/S,可以有全局变量,可以建立客户端缓存,给client一个code,client就会根据本地信息知道code对应的name。
2)ASP.NET 这种web应用的话,代码都是运行在server端的,所以由一个code不够,最好是由一个district实体,想要什么属性都可以,而且不存在数据要传输到client,就是几个server之间传输,搞个缓存加快速度,但是silverlight的代码是运行在client端的,就好像一个C/S程序,而且数据从server到client需要序列化,应该尽量减少传输的数据量。
所以,有时候,一个code就够了。总之,满足要求即可,不必要追求摆放一个关系实体和一个parent好看和好理解的固定模式,可以视情况而定。