第一个疑问是,如果采用ORM,那么是否还需要存储过程?
存储过程的用处不仅仅是效率的提升,更重要的应该是提升了数据库对于系统中数据访问层的清晰度,数据库提供给数据访问层的,不再是一个通用的可以执行SQL语句的入口,而是更像接口函数一样的存储过程。
但是,ORM的出现,使得数据访问层在系统中的作用大大降低,由于ORM可以自动对Entity对象与数据库中的Table进行字段与属性的映射,所以我们实际可能已经不需要一个专用的、庞大的数据访问层。存储过程的作用也就变得模糊起来。
想想ORM诞生的一个原始动力,使我们可以在不需要了解低层数据库的基础上,就可以直接利用它,而不需要再去了解SQL这些数据库的东东。(Java环境中著名的Hiberate的意思就是冬眠,让数据库和SQL语句冬眠。)而再去写一个个的存储过程,反而违反了ORM的初衷。
OK,于是再引出第二个问题。如果我们在系统中全面采用ORM访问数据库(在.Net Framework 1.2中,这叫Accessing data with ObjectSpaces替代Accessing data with Ado.net),是不是降低了我们系统的灵活性了呢?
在实际的系统中,每个数据层决不仅仅就只是那统一的几个方法(返回所有数据、根据ID返回数据,根据Parent的ID返回Child数据,根据ID更新数据....等等...),为了让它工作得更好,我们总会根据具体的情况增加一些必要的方法(根据××返回记录行数...)或更特殊的方法。在这样的场合,ORM显得很笨拙,要实现同样的效果,需要费更多的周折。
不知大家怎么看待这个问题,有何看法和见解?哇,过十点半了,闪人,回家乐......
SDK是EAP(Early Adopters' Preview)版本的,这个版本可以跑在.Net Framework 1.1下面。整个并不复杂,用法也很简洁明了。
/*
TableMappings.xml是一个描述表与实体对象的对应关系(表中的哪个字段对应实体对象的哪个Property)的xml文件。
DataSource.xml是一个描述数据源信息(基本上就是给一个连接字符串)的xml文件。
ObjectSpace类用来维护数据库与实体对象间的连接。
*/
ObjectSpace os = new ObjectSpace(”TableMappings.xml”,”DataSource.xml” ) ;
/*
ObjectContext是一个维护实体对象的类
*/
CommonObjectContext context = new CommonObjectContext(os.ObjectMappings);
/*
随手写的例子,一个Person类,假设已经定义好
*/
Person kaixin = new Person();
kaixin.FullName = “开心”;
kaixin.Age = 27;
/*
把这个实体对象加入到ObjectContext对象中
*/
context.Add(kaixin);
/*
通过ObjectSpace对象的Update()方法,把这个新增的实体对象写回数据库
*/
os.Update(context, kaixin, UpdateOptions.Default);
/*
通过ObjectReader对象把数据库中所有FullName为'开心'的数据读出来
*/
ObjectReader reader = os.GetObjectReader(context, new ObjectQuery(typeof(Person), “FullName = '开心'” ) ) ;
/*
遍历取出的数据,注意,从reader中取值不需要做Cast操作哦
*/
foreach(Person p in reader) {
Console.WriteLine(“Age of {0} is {1}.”, p.FullName, p.Age.ToString());
}
当然啦,如何在那个传进ObjectSpace构造函数的TableMappings.xml文件中定义好表与实体类,字段与属性的关系,是关键啦。这个文件中还可以定义Insert、Update、Delete用哪些StoredProcedure来处理等等,当然,也可以描述Parent-Child关系。
直接在这里打的代码中的双引号会自动转成全角的,呵呵。
这两天好累啊,眼睛都有点红红的,今天早点闪,回家。
家里电脑上装上了.Net Framework 1.2,文档里面好像比1.1多了不少东东,至少看到了ObjectSpaces了。
好像是在ccboy那里看到说蓝色理想把1.2的文档至少看两遍了,强人啊...不过蓝色理想的站点上的确不少ASP.Net 2.0的东东。
最开始做SharePoint的那个项目的时候,就把用户放在了域-OU里面管理,就是计划以后可以和Exchange Server整合。
今天从网上把Exchange Server 2003的SDK下载了回来,准备将用户的邮件管理的一些东西和SharePoint结合起来。
下一步的计划是把工作流(报表、公文审批)加进来。
微软已经在MSDN站点和ASP.NET站点新增了Whidbey的内容,不少图片:
http://www.asp.net/whidbey/
http://msdn.microsoft.com/asp.net/whidbey/
Longhorn的SDK也出现在了MSDN上,看来Win32 API的确可能快走到头了,SDK Refrence里面看来都是.Net的东东,在Longhorn下开发看来已经离不开.Net了。
为什么偶盼望PDC呢,因为看来PDC上会公布不少有关Longhorn和Whidbey的东东,很可能也会给参与大会的人员分发Whydbey PDC Preview版(就像当年也是在PDC上给与会者分发VS.Net PDC Preview版一样),那网上也很快会有相关的下载,那偶不就...嘿嘿...
OPF.Net是一个实现ORM的类库,http://www.littleguru.net/index.aspx,感觉其整个结构还是不错,就是太过烦杂了,我想如果真用起来肯定写代码也是比较麻烦罗嗦。
各位在项目开发中有用一些ORM的产品吗?还是都是干脆自己写?
今天看别人的一段代码,看到他的集合类都是通过继承CollectionBase类来实现的,赶紧看MSDN帮助,才发现.net已经提供了三个抽象的类来给我们继承以实现自定义的集合类:
CollectionBase 基本的集合类
ReadOnlyCollectionBase 只读的
DictionaryBase 基本的key-value集合类
惭愧惭愧,以前自己的代码中的集合类都是通过实现IList,然后通过聚合(内部的一个ArrayList)来实现,呜呜...
看来学习永无止境啊...努力!
http://www.dotnettools.org/download/com/realizing_potential_dopod.wmv
是微软的广告,相当棒。
我想,里面体现的理念,可能就是微软的目标和企业文化吧,就像当年Bill Gates的“让每个办公桌上都有一台PC”。这样的企业理念比国内公司的那些空洞、大话、没人相信的所谓企业理念和企业文化要更能被员工接受并鼓舞员工前进吧?
我们定制的基于SharePoint Service的站点中的用户管理,在增加新用户时包含了两个动作:
1、通过.Net中的DirectoryService在相应的OU(我们给每个客户分配了一个OU,以便于管理)中增加一个用户;
2、把第1步创建的用户增加到当前SharePoint站点的用户中
在做第一步时遇到一个问题,因为新增用户这个操作是给用户站点的管理员进行的,而用户站点管理员这个用户帐号在服务器上并不是属于Domain Admin的角色,所以是没有通过Active Directory新增用户帐号的权限的。
解决方法是利用角色模拟,在需要新增域中的用户时,模拟一个具有这个权限的用户进行模拟,完成这个操作后,再结束模拟。
WindowsIdentity类是用来描述Windows用户的类,它有一个方法Impersonate(),可以模拟某一用户,但是它需要一个IntPtr类型的表示要模拟的用户的Token Handle来作为参数,这时需要用到Win API来得到这个Handle,所以自己又写了一个类来封装这个操作。
示范代码:
// IdentityImpresonation是自定义的用来表示用户模拟的类,构造函数
// 参数分别为:要模拟的用户的用户名、密码、所在域(或机器名)
IdentityImpersonation imper = new IdentityImpersonation("tsg", "123456", "webreal");
imper.BeginImpersonation();
// 进行某些操作
imper.StopImpersonation();
这个类的源码:http://blog.joycode.com/kaneboy/posts/3801.aspx
实质上是通过WindowsIdentity.Impersonate()的方法,其中需要调用Win API来获得活用的Handle,用法其实很简单,因为在自己的代码中需要用到,就稍微封装了一下:
?public class IdentityImpersonation {
??[DllImport("advapi32.dll", SetLastError=true)]
??public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
???int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
??[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
??public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
???int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
??[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
??public extern static bool CloseHandle(IntPtr handle);
??// 要模拟的用户的用户名、密码、域(机器名)
??private String _sImperUsername;
??private String _sImperPassword;
??private String _sImperDomain;
??// 记录模拟上下文
??private WindowsImpersonationContext _imperContext;
??private IntPtr _adminToken;
??private IntPtr _dupeToken;
??// 是否已停止模拟
??private Boolean _bClosed;
??public IdentityImpersonation(String impersonationUsername, String impersonationPassword, String impersonationDomain) {
???_sImperUsername = impersonationUsername;
???_sImperPassword = impersonationPassword;
???_sImperDomain = impersonationDomain;
???_adminToken = IntPtr.Zero;
???_dupeToken = IntPtr.Zero;
???_bClosed = true;
??}
??~IdentityImpersonation() {
???if(! _bClosed) {
????StopImpersonation();
???}
??}
??public Boolean BeginImpersonate() {
?
???Boolean bLogined = LogonUser(_sImperUsername, _sImperDomain, _sImperPassword, 2, 0, ref _adminToken);
???
???if(! bLogined) {
????return false;
???}
???Boolean bDuped = DuplicateToken(_adminToken, 2, ref _dupeToken);
???if(! bDuped) {
????return false;
???}
???WindowsIdentity fakeId = new WindowsIdentity(_dupeToken);
???_imperContext = fakeId.Impersonate();
???_bClosed = false;
???return true;
??}
??public void StopImpersonate() {
???_imperContext.Undo();
???CloseHandle(_dupeToken);
???CloseHandle(_adminToken);
???_bClosed = true;
??}
?}
?
使用示例:
IdentityImpersonation imper = new IdentityImpersonation("tsg", "123456", "webreal");
imper.BeginImpersonation();
// ...
imper.StopImpersonation();
每天都是很晚才睡,又一直有点感冒,所以这几天人都不是很精神,吃饭也提不起劲。
昨晚没呆在办公室,下了班吃了饭就跑去女朋友公司了,她在一家规模挺大的培训学校做老师,那家公司是属于典型的“包身剥削式”公司,每天老师晚上还得抽出时间跑到街边发学校的宣传单,昨晚帮她一起在街上发单,偶总是一次就给别人两份,嘿嘿,100份宣传单挺快就发完了,估计其中90张在半小时内都会被人随手扔掉。然后就手牵手送女朋友回去了。不久还是得帮她另找工作。
有人听说过微软的一个叫ObjectSpaces的类库吗?是一个做OR Mapping的东东。今天和MSN Messenger上的朋友谈到ORM,他提到了ObjectSpaces,于是在网上找了一下,好像微软很早就开始ObjectSpaces的开发了,在.Net Framework PDC Preview版出来后就发布了一个测试的版本,但.Net Framwork正式发布后,反而没有消息了。现在微软正式的说法是,还在开发之中,可能2004年面世。
找到了ObjectSpaces的安装文件,可惜它只认.Net Framework PDC Preview版,呵呵,没法安装,看了一下例子,是包含在Microsoft.ObjectSpaces命名空间里面的,没仔细研究。说不定微软早把这个产品Over掉了也说不定,呵呵。
不过网上倒是能找到不少.Net的ORM产品,有开源的,也有商业产品。奇怪,今天我又看不了SourceForge了,郁闷。
一个SharePoint中DiscussionBoard的问题困扰了一天。从SDK文档到微软新闻组,CodeProject论坛,DevX论坛,sharepointu.com论坛,被我都搜了一遍,极少有关SharePoint Service 2003的文章或帖子,晕啊...
把问题贴在了微软新闻组,结果就是SharePoint.TeamService的斑竹跟贴告诉我不应该把Service2003的相关的帖子贴到TeamService版(版本不同),继续晕...
晚上把IBuySpy Portal装到了电脑上,准备这段时间把IBuySpy的程序结构看一遍,不愧是微软的示范程序,结构清晰,很多用法是我以前都从没用过的。当然,也多亏代码里面注释很详细啦,嘿嘿...
不过感觉IBuySpy的数据存取架构很简单,没有像一些系统那样搞得层次分明而复杂,优点就是代码和网站结构都很清晰,整个网站由各种Module组合起来,而且可以自己写Module加进去。
有研究过微软的PetShop、Duwamish的大虾也发表自己的心得啊。
今天想利用它自带的DiscussionBoard功能接口来实现一个讨论板,SharePoint的对象模型总是有点奇怪,而SDK文档里面除了有一点说明对文档的操作的文章之外,既没有如何利用对象模型操作DiscussionBoard的文章,只能根据对象的Reference手册来猜测了...晕啊...
深圳的动感地带卡开通了GPRS功能,20元包月(注意,不是200!),但是只开放CMWAP,不开放CMNET,就是说,只能连接wap站点,不能去访问internet上的东东。但是网上有人通过一些方法,是电脑连接手机后,依然可以用IE访问网站。早就想让家里的电脑能够上网了,又心疼ADSL每月200的包月费,于是把GF的西门子2128借来(偶的西门子6688不支持GPRS),又去买了一条兼容的数据线,上深圳移动的网站把我的卡开通了GPRS业务,然后先用手机试了试,上wap没问题,于是迫不及待的用数据线连上电脑,从西门子网站上把gprs modem驱动下载回来,安装上,检测gprs modem设备,手机立马自动关机了,再试,还是自动关机,晕...
晚上回家里了再用家里的电脑试试。
有个朋友让我谈谈SharePoint2003的文件存储机制,正好这个月一直在做与SharePoint相关的工作,随便说说吧。有对SharePoint很熟悉的朋友也可以对我的理解加以指导和纠正。
SharePoint这个词包含两个东东,一个是Team Service,这是一些服务,提供了方便的站点、文档等东东的管理,以编程接口的方式提供,我们可以直接通过其SDK来调用其服务,现在最新的2003版已经集成进Windows Server 2003了(通过Windows Update就可以安装,或者去MS网站上下载),名字也叫做Windows SharePoint Service 2.0了。
另外一个就是Portal Server,这是一个可以直接建立门户站点的东东,安装上以后,通过其Adminstration Center,就可以直接在IIS的虚拟主机上直接建立站点,并把诸如文档库、列表、论坛等模块加入到站点中。最新的版本是Portal Server 2003,MS中国站点首页上已经有中文版的广告了。
其实上,Portal Server也是调用后面SharePoint Service的接口,只不过把站点的模板都做好了,可以直接拿来用了。Portal Server定义了一种CAML,用来描述站点页面模板。不过偶自己的感觉是是这个东东并不方便,改Portal Server的模板太麻烦了。
SharePoint Service是免费的,Portal Server是要钱的(估计价格不会很低)。
SharePoint里面一个很有特色的东东是WebPart,实质上就是一个CustomControl,特别的是,它可以在Portal Server的站点上,由用户自定义把一个WebPart放在页面上。
SharePoint把所有的东东都存放在Sql Server 2000里面的,文档、图片...只不过通过编程接口可以以更直接的比如SPFolder、SPFile对象把他们当作文件夹、文件来处理(实际上站点服务器上是不会真的给你建立这些文件夹、文件的,都存放在数据库里面)。如果以单服务器模式安装Portal Server,它会自动给你装上一个MSDE。
另外顺便提一下,好像现在在web程序中使用Access的情况是越来越少了,以前ASP时代,很多程序都用Access来保存数据,现在越来越多的是宁愿用MSDE,少量数据则用xml。
我觉得VS2003中最差的地方就是那个所谓WYSIWYG的网页设计器了,以前一直是用DW的,所以越发觉得这个内置的设计器差劲了,难道MS不能把这个设计器做得好用一些吗?
1、这个设计器自动生成的HTML垃圾代码多多
2、还可能自动格式化我手工写的HTML
3、从设计器中看到的效果和在IE中看到的差别大大
唯一好的,就是对ASP.NET的WebControl支持好(自家东西),而DW在这方面就差了。
昨晚看新买的书到两点半,现在头都有点沉...看来只能借助鹊巢了。
Wrox版图书的特点:原书内容的确不错,翻译的确垃圾(语句不通也就算了,居然常常把原来的意思翻译得倒过来)
呵呵,送货上门、货到付款,看来网上书店是中国B2C电子商务做得最好的了。
买了一个Wrox的关于ASP.NET的书和一本Oreilly的《JSP设计》,呵呵,公司里面不少JSP程序员,不学都觉得浪费资源的说...:)
偶在进现在的公司之前是做Delphi的,心仪.NET,所以就跑到.NET公司跟随了微软。以前还写过一篇在Delphi中模仿ADO.NET类的文章(http://www.csdn.net/develop/read_article.asp?id=20609)。不过心里还是颇为期待Delphi.Net的发布。
来这家公司已经一个多月了,我们部门是给中小企业提供Web的一些应用服务,以前用Java+JSP做了一套系统。部门的技术经理招聘我的时候,就说过以后会用.net基于SharePoint做一些开发,进来以后,就交给了我对SharePoint 2003进行一个技术跟踪和评估的工作。
我以前对SharePoint的了解仅限于MS的一些新闻报道,接到这个任务,只好硬着头皮开始从网上搜索资料,先是了解了一下SharePoint是什么东东,然后在微软网站上找到了SharePoint Portal Server 2003 beta 2和相应的SDK,装上,然后开始用起来了。
后来,和技术经理一起确定了一个开发的方向,以SharePoint Service为基础,利用其SDK开发一个文档管理(包含用户、权限管理)的产品,还可以美其名曰“知识管理”或“内容管理”之类的新名词,呵呵。
从上个月底开始,现在已经形成了一个产品的雏形,今天上午去公司会议室给老总和部门经理演示了一下,老总还比较满意,特别是SharePoint和客户端的Office紧密的结合令人颇为欣赏。老总不希望把这个产品做得太大,认为仅是文档库,就可以很大程度上满足客户需求了。计划十月底推出内部试用版。
Windows SharePoint Services SDK:
http://www.microsoft.com/downloads/details.aspx?FamilyID=1c64af62-c2e9-4ca3-a2a0-7d4319980011&DisplayLang=en
另:感谢开心给我开了这个Blog帐号,呵呵。:)