T-SQL更新替换为存储过程
O/RM工具选择了动态生成的SQL语句而不是查询的存储过程,甚至没有选择更新数据存储,关于这点存在着很大的争议。默认情况下,LINQ to SQL从LINQ的From … In … Where … Order By … Select查询创建的表示树产生SELECT语句。类似地,添加、更新、或移除一个实体实例,并调用DataContext.SubmitChanges()方法会向数据库发送T-SQL INSERT, UPDATE, or DELETE语句。可以从DataContext.Log产生一个TextWriter来写日志文件,或者是一个StringBuilder来存储或显示LINQ to SQL发送到SQL Server 200x实例的命令。下面的代码向文本框txtSQL写入内容:
Private sbLog As New StringBuilder不需用SQL Profiler来检查LINQ to SQL发出的命令,这对运行SQL Server Express的程序开发人员来说是一个福音,并且对那些拥有全套SQL Server客户端工具的用户而言,非常节省时间。
Private swLog _
As New StringWriter(sbLog)
...
dcNwind = New NwindLINQDataContext
dcNwind.Log = swLog
...
txtSQL.Text = sbLog.ToString()
LINQ to SQL的O/R Designer让我们可以用方便的存储过程来替换SELECT, INSERT, UPDATE, 和DELETE T-SQL批处理。从Server Explorer拖动SELECT 存储过程节点到Designer的表面,在Methods边窗添加StoredProcName(ParameterList),局部公有类 StoredProcName实体类,和DataContext的公有函数StoredProcName。这个函数返回StoredProcName实体,比如uspGetCustomersByCountry。添加一个采用了IMultipleResults接口,但是向局部类文件返回一个单一结果的重新命名的函数。这样就可以返回事先定义好的,兼容的实体,而不是根据存储过程命名的实体。
要注册INSERT, UPDATE, 或DELETE存储过程,只需从Server Explorer拖动相应的节点到Designer表面。在这个例子中,你必须右键点击entity-class,得到相应的表,并选择Configure Behavior,打开相同名字的对话框,在其中你就可以让储存过程和一个已经存在的实体类联系起来。选Accept或选择对话框里Class列表中的实体类,然后在Behavior列表中选择Insert,Update,或Delete。选择Customize选项,打开已注册存储过程列表,并选择实体和行为恰当的一个,从而加入Method Arguments和相应的Class Properties列表。更新的时候,选择PropertyName(原来的)找到要更新的行的主键。
PropertyName(当前的)项目指定更新的值。点Apply或OK生成Sub InsertEntityName,Sub UpdateEntityName,或Sub DeleteEntityName重载方法和相应的执行存储过程的函数StoredProcName。在代码调用DataContext.SubmitChanges()方法之前,这些方法是不会被执行的。(Beta 1 介绍了使用存储过程来更新时的几个问题。但是这些问题在CTP或Beta 2.0中都会得到修正。可以在这篇博客里找到关于这些问题的描述http://tinyurl.com/2o23ch)。
可以通过用时间戳列(用于处理并发冲突)来代替原值参数,从而简化存储过程的代码。例如:更新Order_Detail的过程更新了增加了时间戳列的Order_Details:
Private Sub UpdateOrder_Detail(ByVal current As _
Order_Detail, ByVal original _
As Order_Detail)
Me.uspUpdateOrder_Detail(original.ProductID, _
current.UnitPrice, current. _
Quantity, current.Discount, _
original.OrderID, original.TimeStamp)
End Sub