上一篇讲到WCF如何正确调用LINQ TO SQL,只涉及到了新增记录的操作。到于为什么要把更新操作分开来讲呢?因为更新确实有点麻烦,相对于新增操作来说,稍微有点难。
     还是使用上一篇的项目,没有源码的兄弟可以到这里下载上一篇的项目:http://files.cnblogs.com/viter/WCF.rar
首先我们新建一个WinForm窗体UpdateForm,在客户端界面添加一个DataGridView,用来存储从服务读取到的数据,命名为:dgvPurchaseOrder,并在代码中设置自动生成列为False。其实用BindingSource更快,呵呵。
     那好,还是使用BindingSource,不过这个BindingSource是自定义的,因为用来做数据显示控制没有比它更称职的了。

BindingSource

 

为这个BindingSource定义一个事件,就是BindingSource的CurrentChanged事件。
这个事件里的代码如下,很简单。

 

CurrentChanged


在界面加载的事件从服务器调取数据
  

client

 

     现在我们的数据出来了,好,我们修改一下订单总额,提交到服务器。
我们将出错信息写到控制台,好好欣赏一下吧,呵呵。好像是真的一样。


     为什么会出现这个错误?我们还是来调试一下,看得更仔细点。

 

     

     看,好像告诉我们,你要修改的数据已经存在,不能添加。想想有点不妥啊!非常不妥,我不是要添加数据,是要修改数据,为什么会提示“无法附加已经存在的实体”?好,注意看,MS用词还是很恰当的,看这一句:“无法附加已经存在的实体”,注意,是实体!!!那意思是我们的操作没有任何的问题,是实体出了问题,再想一下,我们的实体是通过什么方式来取得的呢?你肯定在电光火石之间想到了,是DataContext,对,是数据上下文,如果你对单张表进行操作,我敢保证你一辈子也不会遇上这个异常,真的不会。好了,现在我们来看下数据库关系图

 

     这两张表是有关联的,不是独立的表。可能这样还是有点看不明白,不要紧,再看一下生成的DBMl文件。
PurchaseOrderHeader类里面有一个属性

EntitySet

 

相对的,PurchaseOrderDetail类里面也有一个对应的属性,用来关联

EntityRef

 

可以看到,这两个属性是标记数据库两张表的一对多的关系。
那么我们分析一下,在我们从数据库检索数据的时候,这个关系是否存在?答案是肯定的!
不好意思,这个图切不下来,各位可以在这里设置断点查看


 

     通过这里可以看到,关系是存在的,只是由于Linq的延迟加载的特性,数据并没有读取出来而已。
那么我们就要问了,在查询的时候会有关系,那么向数据库添加数据的时候呢?看一下下面的表格,已经有很好的答案


 

     好了,既然要关系,我们就加一个试试,在这之前你需要引用System.Data.Linq.dll,并引用System.Data.Linq命名空间。
加关系很简单,在原来的Update方法里面加一个判断就可以了,如果是修改或删除的操作,那么我们就给它加上关系。
1~~*和*~~1的关系设置不一样,注意代码里面的设置。

 

关系


好,我们现在来修改订单编号为1的记录,将订单总额改为5000.

成功!


 

 

欢迎转载,但请注明出处--梁规晓博客(http://www.cnblogs.com/viter/)!
下一篇将介绍“如何将WCF和WF无缝的结合”。谢谢大家的关注!

点击下面下载服务端和客户端源代码.

http://files.cnblogs.com/viter/WCF2.rar

说得不对的地方,欢迎拍砖!

posted @ 2008-09-01 13:14 veter 阅读(1331) | 评论 (2)编辑
     摘要: 在上一篇,我们说到了通过设置Linq上下文的Serialization Mode属性为Unidirectional,使Linq自动支持WCF的序列化。在这一篇我想说一下如何设置Linq实体类各种属性使WCF可以正确的调用Linq完成数据操作,并通过一些异常来说明为何要那样去做,并且在这一次,我会加入一些调料,比如工厂模式。好吧,让我们马上开始!项目还是使用上一篇所建立的采购项目,如果有不明白的朋友... 阅读全文
posted @ 2008-08-03 23:11 veter 阅读(1088) | 评论 (6)编辑

 这篇文章准备了很长时间,真的是没时间写.今天就来完善吧!在我之前的Linq对WCF序列中的解决方案(参考http://www.cnblogs.com/viter/archive/2008/03/27/1126203.html),我说过这个方案并不很
好,一直在寻找更好的解决方案.
      那我们就以一个"商品采购"来作为开篇吧.这个"商品采购"的解决方案将会在这个系列中一直存在.废话少说,来看需求说明.
客户在登录网上采购系统后,将会进行采购操作,涉及"采购入库,采购结算",为了让大家更容易理解,这个采购将会很粗糙(简约而不简单),呵呵
.OK,来看,数据库将会产生二张表,采购订单头(PurchaseOrderHeader),采购订单细目(PurchaseOrderDetail);这个数据库使用了
微软的示例数据库(AdventureWorks).
     首先我们建立一个解决方案: PurchaseDemo
     添加一个类库,接着在类库里面添加Linq to sql类,并取名为Purchase,系统将会自动帮我们重命名为:PurchaseDataContext,
好了,现在切换到设计视图,什么都没有,没关系,把建好的表拖进来吧!

          

          

          细心的朋友可能会发现,这两张表都有一个字段叫做(timestamp),类型和名称一样的,后面我们再介绍是干啥用的.现在没必要,只要你注意到它的存在就可以了.
     选择PurchaseOrderHeader(把自增列和RowGuid及timestamp列都设置为自动生成),就是把Auto Generated value 设为true,PurchaseOrderDetail表也如法炮制.


          

          好,现在来看最重要的,不要选中任何表,在dbml的设计页面上右击选择属性,把Sericlization Mode值改为:Unidirectional.


          好了,现在保存文件,打开dbml的代码看看每个类的头顶多了什么东西?

     

        

 

 

          类中的属性又多了什么东西,天呀,漂亮的帽子(DataContact和DataMember).很好,这就是我们想要的,只要
我们把Linq上下文的序列化模式改为单向,它将会自动的支持WCF的序列化,真的就这么简单?对对对,真的就是这么简单!

 

          现在你的Linq to sql中的类已经可以支持WCF直接序列化到客户端了,但是请注意,有一点小小的遗憾.就是自从Linq上下文改为序列化单向后,所有的关系都只能在服务器使用,客户端是一点都没有的,唉~~,难道天要绝我?不要!


          突然被电击了一下,灵光突现.Partial关键字,对,就是它了.马上动手,为PurchaseOrderDetail和PurchaseOrderDetail添加一个部分类,
并添加两类之间的关系,并手动加上DataMember标记为可支持WCF序列化,

                    

 

 

          以后不管DBML文件怎么改动,这个关系都是可以不变的.解决!当然,如果你现在要用这两个类直接进行数据操作的话
,不好意思,是会出错的.这一篇只是介绍"Linq对WCF的序列化支持",关于数据操作,将会在下一篇继续...

          如果有说得不对的地方,欢迎拍砖~.

 

点击这里下载源代码(内含sql文件).

http://files.cnblogs.com/viter/PurchaseDemo.rar 

 

posted @ 2008-07-27 17:48 veter 阅读(1010) | 评论 (13)编辑
        写之前,犹豫了很长时间,不懂这个初级分析会不会引起园友的批判,说实在,在博客园发贴,真有点诚惶诚恐的感觉,很怕对不住大家。
        前段时间花了一个星期给客户做了一个OA系统,用的是Win2008的系统,VS2008+Access数据库做的,本来客户已有一个ASP的主机,因为考虑到现在本本上确实没装有其它的开发环境了,就直接上.net3.5了。当做好想当然的直接上传到服务器,不想总是运行不起来。
总结了一下,问题如下:
1:访问静态页面无任何问题,但是.aspx就不行,总是报一个服务器出错。但具体错误又没有提示。
2:无法加载DLL文件
3:首页登录图片显示不完整。

        刚开始一直在和客服联系,以为是他们的服务器不支持,因为我在本地部署是没有任何问题的。后来他们说服务器是没有问题的,应该是程序的问题。
然后我试着在本地IIS新建一个虚拟目录来运行,果然也是不行的,报出的错误是一样的。新建网站是可以直接运行的。
        分析如下:
1:IIS7会不会和IIS6一样,默认编译语言是VB?
2:应用程序配置文件的存放目录是不是不正确?
3:网站编译后的BIN目录是不是没有被页面访问到?
4:页面之间的访问路径是否正确?
5:数据库文件是否有执行全部权限?


带着以上问题,我一个个的去查找。
         问题1:找到服务管理器下面的IIS的默认网站,切换到“功能视图--.net编译项”,打开一看,果然默认编译语言是VB,好,第一个问题搞定。
         问题2:配置文件改放到默认网站根目录下面,把原来IIS自带的配置文件覆盖掉,再运行,好,可以访问到登陆页面了,但是登陆页面的图片总是显示不出来,想想应该是路径问题,接着将目录IMAGE也放到根目录,刷新后图片显示出来了,但是验证码没有,怪了。为什么呢?
再次分析,因为验证码是用一个.aspx页面生成一个流后写入到Cookie中的,会不会是也是路径问题?接着把验证码页面再放到根目录下,果然OK。
        问题3:关于DLL文件执行权限问题,其实DLL文件是生成到了BIN目录下面,所以应该是这个目录的执行权限问题了,接着在IIS中打开此目录属性,找到一个叫做:IIS_IUSER的用户,编辑此用户权限,使其拥有对BIN的全部权限。再次运行,OK,访问到了,但是数据库又出错,找不到可用的连接。
真是怪了,为什么呢?明明数据库就是和SERVER层放在一起的呀!而且页面可以访问到数据库呀,为什么SERVER不行呢?我们先来分析问题4.
        问题4:我的首页上有一颗树,在生成树时,我用了硬编码方式(时间紧),导致了导航的URL总是自动上"~/",  在发布时没注意到这个问题,所以页面间访问时,总是说找不到路径。把这个"~/",去掉后问题解决,其实这是小问题了,个人没注意到。
        问题5:数据库文件问题,终于来到这个重头了。其实不懂是不是IIS中虚拟目录的问题,要解决这个问题,只要你在网站根目录下建好一个叫做App_Data的目录,再将你的ACCESS数据库放进去就差不多了,只所以说差不多,因为还要再做一件事,和BIN目录一样,IIS_IUSER的用户对这个目录也是没有写入权限的,你查询数据没问题,但是你要写入,不好意思,出错。
        问题到这里解决得差不多了,最后按照解决问题的步骤将网站放到服务器上,一运行,还是不行,咦,真是怪事年年有,今年特别多啊!
心想死马当做活马医吧,再次把BIN目录COPY到虚拟目录下,注意,只是COPY,根目录下还是有一个BIN目录的,虚拟目录下的配置文件删除,再次访问登陆页面,输入用户名密码,成功!再试一下其它的操作,一切OK!
        直到这一步,距系统完成已过去了三天,网上广发贴子,无人回应,百度GOOGLE找不到任何帮助,头真是大。
      
posted @ 2008-06-07 16:05 veter 阅读(3283) | 评论 (18)编辑
如题,代码就不多说了,因为在代码里有详细的注释!WCF远程调用Linq源码下载
posted @ 2008-04-03 21:42 veter 阅读(82) | 评论 (0)编辑