DataContext向UpdateEntityName方法提供当前和原始的值作为参数。InsertEntityName方法只有一个当前的参数,而DeleteEntityName 方法有一个原始的参数。
这是通过映射来执行存储过程的uspUpdateOrder_Detail函数的代码:
<DebuggerNonUserCodeAttribute(), _
StoredProcedure(Name:= _
"dbo.uspUpdateOrder_Detail")> _
Public Function uspUpdateOrder_Detail( _
<Parameter(Name:="@ProductID")> _
ByVal ProductID _
As Global.System.Nullable(Of Integer), _
<Parameter(Name:="@UnitPrice")> ByVal _
UnitPrice As Global.System.Nullable(Of _
Decimal), <Parameter(Name:="@Quantity")> _
ByVal Quantity As Global.System.Nullable(Of _
Short), <Parameter(Name:="@Discount")> _
ByVal Discount As Global.System.Nullable(Of _
Single), <Parameter(Name:="@OrderID")> _
ByVal OrderID As Global.System.Nullable(Of _
Integer), <Parameter(Name:="@TimeStamp")> _
ByVal TimeStamp() As Byte) As Integer
Dim result As Provider.IExecuteResults = _
Me.ExecuteMethodCall(Me, CType( _
MethodInfo.GetCurrentMethod, _
MethodInfo), ProductID, _
UnitPrice, Quantity, Discount, _
OrderID, TimeStamp)
Return CType( _
result.ReturnValue,Integer)
End Function
请注意,为简洁起见,我删除了Global.System.Diagnostics, Global.System.Data.Linq, 和Global.System.Reflection的名称空间前缀。
解决并发冲突
如果执行INSERT, UPDATE, 或DELETE语句,或者执行存储过程影响到的行数为0, 则DataAdapters会抛出DbConcurrencyException。异常的Row属性会返回引起第一个异常的DataRow对象。解决这个冲突问题通常需要编写相当数量的事务逻辑代码,并且不容易测试。在很多情况下,当试图更新相关记录的时候,都要处理很多被抛出的异常。
在执行LINQ to SQL的DataContext.Submit-Changes(ConflictMode.ContinueOnConflict)重载的时候,DataContext.ChangeConflicts属性会返回一个Change- ConflictsCollection(ObjectChangeConflict的),其中每一个发生了并发冲突的对象都有一个对应的成员。ObjectChangeConflict的成员包含一个MemberConflicts(MemberChangeConflict的)集合,其中包含有冲突的成员。对象成员ChangeConflict有OriginalValue, Current-Value, 和DatabaseValue属性,同样也有重载后的Resolve方法来以参数的形式接受Refresh-Mode.Keep-Changes,RefreshMode.KeepCurrent-Values,或RefreshMode.OverwriteCurrent-Values。这些嵌套的集合允许事务-规则代码或用户能够用一对嵌套的For Each … Next循环(产生一个简单的消息框)来解决多冲突问题。本文的LINQ2SQL.sln例子工程包含了一个ProcessChanges过程,其中就有会产生这种消息框的冲突解决代码。
一些β测试员把LINQ to SQL的实体类称作是“荣耀类型的Data-Sets”,我把这叫做假赞美,真诅咒。LINQ to SQL的O/R Designer和DataSet 设计器有一些相似之处。从这些实体类创建的Object Data Sources提供了和DataSets类似的数据绑定能力。然而,LINQ to SQL的内在哲学已经从操作高速缓存的DataRows集合转变到支持LINQ查询的内存中的用户-业务对象集合。下载LINQ2SQL.sln工程和它的NwindLINQ.mdf数据库。在以下几个方面和BindingNavigators进行性能比较:Tables跳转,LINQ查询,或SELECT存储过程的结果,以及在多个对象实例上INSERT,UPATE,DELETE操作的执行时间。通过比较反衬出和Data-Sets相比,LINQ to SQL编码技术的简单。甚至在这个早期的β阶段我就认为LINQ to SQL会赢得SQL Server 200x用户。