Linq To Sql进阶系列(五)Store Procedure篇
2008-11-05 11:33
267 查看
Store Procedure,存储过程。也是被别人写过的东西。我习惯性先看别人都写了点啥,然后才开始想看看自己还要写点啥。那就先谈谈它与udf的区别吧。
在Linq To Sql进阶系列(四)User Define Function篇 中,我们提到了两者的差别。比如Store Procedure支持多个rowset的,而udf不行。他们还有一些其他的差别。Store Procedure只能返回整型,而udf可以是其他类型,比如char等,除个别类型外,比如imager类型,是不可以做为udf的返回类型的。Store Procedure支持Out Parameter而udf没有。
1, SingleResultSet
我们先来看这个sprocs.
CREATE PROCEDURE [dbo].[Customers By City]
-- Add the parameters for the stored procedure here
(@param1 NVARCHAR(20))
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT CustomerID, ContactName, CompanyName, City from Customers as c where c.City=@param1
END
其生成的code如下。
[Function(Name="dbo.[Customers By City]")]
public ISingleResult<Customers_By_CityResult> Customers_By_City([Parameter(DbType="NVarChar(20)")] string param1)
DataClasses1DataContext db = new DataClasses1DataContext();
db.Log = Console.Out;
var q = db.Customers_By_City("London");
正因它不是延迟加载的,所以,linq可以对他进行简单的内联操作,比如
DataClasses1DataContext db = new DataClasses1DataContext();
db.Log = Console.Out;
var q = from c in db.Customers_By_City("London")
orderby c.City
select c;
注意的时,这里是Linq To Object而不是Linq To Sql。
2, MultipleResultSets
看下面的例子
CREATE PROCEDURE [dbo].[Get Customer And Orders](@CustomerID nchar(5))
-- Add the parameters for the stored procedure here
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT * FROM Customers AS c WHERE c.CustomerID = @CustomerID
SELECT * FROM Orders AS o WHERE o.CustomerID = @CustomerID
END
使用OR designer对其影射,其dbml为
<Function Name="dbo.[Get Customer And Orders]" Method="Get_Customer_And_Orders">
<Parameter Name="CustomerID" Parameter="customerID" Type="System.String" DbType="NChar(5)" />
<ElementType Name="Get_Customer_And_OrdersResult">
<Column Name="CustomerID" Type="System.String" DbType="NChar(5) NOT NULL" CanBeNull="false" />
<Column Name="CompanyName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
<Column Name="ContactName" Type="System.String" DbType="NVarChar(30)" CanBeNull="true" />
<Column Name="ContactTitle" Type="System.String" DbType="NVarChar(30)" CanBeNull="true" />
<Column Name="Address" Type="System.String" DbType="NVarChar(60)" CanBeNull="true" />
<Column Name="City" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
<Column Name="Region" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
<Column Name="PostalCode" Type="System.String" DbType="NVarChar(10)" CanBeNull="true" />
<Column Name="Country" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
<Column Name="Phone" Type="System.String" DbType="NVarChar(24)" CanBeNull="true" />
<Column Name="Fax" Type="System.String" DbType="NVarChar(24)" CanBeNull="true" />
</ElementType>
</Function>
用sqlmetal对它做影射,生成dbml为
<Function Name="dbo.Get Customer And Orders" Method="GetCustomerAndOrders">
<Parameter Name="CustomerID" Parameter="customerID" Type="System.String" DbType="NChar(5)" />
<ElementType Name="GetCustomerAndOrdersResult1">
<Column Name="CustomerID" Type="System.String" DbType="NChar(5)" CanBeNull="true" />
<Column Name="CompanyName" Type="System.String" DbType="NVarChar(40)" CanBeNull="true" />
<Column Name="ContactName" Type="System.String" DbType="NVarChar(30)" CanBeNull="true" />
<Column Name="ContactTitle" Type="System.String" DbType="NVarChar(30)" CanBeNull="true" />
<Column Name="Address" Type="System.String" DbType="NVarChar(60)" CanBeNull="true" />
<Column Name="City" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
<Column Name="Region" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
<Column Name="PostalCode" Type="System.String" DbType="NVarChar(10)" CanBeNull="true" />
<Column Name="Country" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
<Column Name="Phone" Type="System.String" DbType="NVarChar(24)" CanBeNull="true" />
<Column Name="Fax" Type="System.String" DbType="NVarChar(24)" CanBeNull="true" />
</ElementType>
<ElementType Name="GetCustomerAndOrdersResult2">
<Column Name="OrderID" Type="System.Int32" DbType="Int" CanBeNull="true" />
<Column Name="CustomerID" Type="System.String" DbType="NChar(5)" CanBeNull="true" />
<Column Name="EmployeeID" Type="System.Int32" DbType="Int" CanBeNull="true" />
<Column Name="OrderDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
<Column Name="RequiredDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
<Column Name="ShippedDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
<Column Name="ShipVia" Type="System.Int32" DbType="Int" CanBeNull="true" />
<Column Name="Freight" Type="System.Decimal" DbType="Money" CanBeNull="true" />
<Column Name="ShipName" Type="System.String" DbType="NVarChar(40)" CanBeNull="true" />
<Column Name="ShipAddress" Type="System.String" DbType="NVarChar(60)" CanBeNull="true" />
<Column Name="ShipCity" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
<Column Name="ShipRegion" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
<Column Name="ShipPostalCode" Type="System.String" DbType="NVarChar(10)" CanBeNull="true" />
<Column Name="ShipCountry" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
</ElementType>
</Function>
仔细比较他们的区别哦。“好像名字不一样呢”。晕倒。看主要的。第一个只有一个ElementType子项,而第二个有2个。这个地方其实可以说是OR designer的一个bug。要想修改这个bug,需要更改一个设计,而推动更改设计,比较麻烦。但并不是不能改。如果你认为这个真的很需要,而且对你很重要,你更喜欢用or designer的话,我建议你去下面的社区发帖子。
http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=123&SiteID=1
要求更改此处的问题。因为,我已经无力推动他们修复该bug,ms更乐意听来自客户的声音,说不定你会成功的哦,还有奖励的哦。
这个sprocs准确的影射代码为
[Function(Name="dbo.Get Customer And Orders")]
[ResultType(typeof(GetCustomerAndOrdersResult1))]
[ResultType(typeof(GetCustomerAndOrdersResult2))]
public IMultipleResults GetCustomerAndOrders([Parameter(Name="CustomerID", DbType="NChar(5)")] string customerID)
CREATE PROCEDURE [dbo].[CustOrderTotal]
@CustomerID nchar(5),
@TotalSales money OUTPUT
AS
SELECT @TotalSales = SUM(OD.UNITPRICE*(1-OD.DISCOUNT) * OD.QUANTITY)
FROM ORDERS O, "ORDER DETAILS" OD
where O.CUSTOMERID = @CustomerID AND O.ORDERID = OD.ORDERID
其影射的code为
[Function(Name="dbo.CustOrderTotal")]
public int CustOrderTotal([Parameter(Name="CustomerID", DbType="NChar(5)")] string customerID, [Parameter(Name="TotalSales", DbType="Money")] ref System.Nullable<decimal> totalSales)
[Function(Name = "dbo.[Customers By City]")]
public ISingleResult<Customers_By_CityResult1> Customers_By_City([Parameter(DbType = "NVarChar(20)")] string param1)
public ISingleResult<Customers_By_CityResult1> Customers_By_City2(string para, out int returnValue)
DataClasses1DataContext db = new DataClasses1DataContext();
db.Log = Console.Out;
int returnValue = -1;
var q = db.Customers_By_City2("London",out returnValue);
Console.WriteLine(returnValue);
也可以使用result.GetParameterValue方法获取返回值。只是linq会检查影射函数的参数个数。这个使用起来比较麻烦。可以这么使用,比如,有一个sprocs,有2个参数,其中有一个out的参数。这个out的参数,可以不做任何操作。在影射后,修改其code。这两个参数的位标是从0开始,依次递增。其code本来为outParameter = ((System.Nullable<int>)(result.GetParameterValue(1))); 将其索引修改位为2,就是return value了。再大了又该抛了。
ps:招聘,我就趁机打个广告吧.呵呵。赴微软测试工程师
1, 计算机或软件,相关专业,本科或硕士以上。
2, 2年及2年以上工作经验。
3, 英语,听说读写流利。
4, 工作认真负责,学习能力强。
5, 精通c#1.1及c#2.0版本语言,对c#3.0有了解。
6, 精通算法。
7, 有Ado.Net 和Asp.Net的经验。技术好。
有意者投简历到guoan@126.com 谢谢
相关文章:
ps:
C# 3.0 入门系列(一)
C# 3.0入门系列(二)
C# 3.0入门系列(三)
C# 3.0入门系列(四)-之Select操作
C#3.0入门系列(五)-之Where操作
C#3.0入门系列(六)-之OrderBy操作
C#3.0入门系列(七)--之OR工具介绍
C#3.0入门系列(八)-之GroupBy操作
C#3.0入门系列(九)-之GroupBy操作
C#3.0入门系列(十)-之Join操作
C#3.0入门系列(十一)-之In, Like操作
C#3.0入门系列(十二)-Lambda表达式中Lifting
Linq To Sql进阶系列(一)-从映射讲起
Linq To Sql进阶系列(二)M:M关系
Linq To Sql进阶系列(三)CUD和Log
Linq To Sql进阶系列(四)User Define Function篇
Linq To Sql进阶系列(五)Store Procedure篇
TrackBack:/article/4785695.html
在Linq To Sql进阶系列(四)User Define Function篇 中,我们提到了两者的差别。比如Store Procedure支持多个rowset的,而udf不行。他们还有一些其他的差别。Store Procedure只能返回整型,而udf可以是其他类型,比如char等,除个别类型外,比如imager类型,是不可以做为udf的返回类型的。Store Procedure支持Out Parameter而udf没有。
1, SingleResultSet
我们先来看这个sprocs.
CREATE PROCEDURE [dbo].[Customers By City]
-- Add the parameters for the stored procedure here
(@param1 NVARCHAR(20))
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT CustomerID, ContactName, CompanyName, City from Customers as c where c.City=@param1
END
其生成的code如下。
[Function(Name="dbo.[Customers By City]")]
public ISingleResult<Customers_By_CityResult> Customers_By_City([Parameter(DbType="NVarChar(20)")] string param1)
DataClasses1DataContext db = new DataClasses1DataContext();
db.Log = Console.Out;
var q = db.Customers_By_City("London");
正因它不是延迟加载的,所以,linq可以对他进行简单的内联操作,比如
DataClasses1DataContext db = new DataClasses1DataContext();
db.Log = Console.Out;
var q = from c in db.Customers_By_City("London")
orderby c.City
select c;
注意的时,这里是Linq To Object而不是Linq To Sql。
2, MultipleResultSets
看下面的例子
CREATE PROCEDURE [dbo].[Get Customer And Orders](@CustomerID nchar(5))
-- Add the parameters for the stored procedure here
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT * FROM Customers AS c WHERE c.CustomerID = @CustomerID
SELECT * FROM Orders AS o WHERE o.CustomerID = @CustomerID
END
使用OR designer对其影射,其dbml为
<Function Name="dbo.[Get Customer And Orders]" Method="Get_Customer_And_Orders">
<Parameter Name="CustomerID" Parameter="customerID" Type="System.String" DbType="NChar(5)" />
<ElementType Name="Get_Customer_And_OrdersResult">
<Column Name="CustomerID" Type="System.String" DbType="NChar(5) NOT NULL" CanBeNull="false" />
<Column Name="CompanyName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
<Column Name="ContactName" Type="System.String" DbType="NVarChar(30)" CanBeNull="true" />
<Column Name="ContactTitle" Type="System.String" DbType="NVarChar(30)" CanBeNull="true" />
<Column Name="Address" Type="System.String" DbType="NVarChar(60)" CanBeNull="true" />
<Column Name="City" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
<Column Name="Region" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
<Column Name="PostalCode" Type="System.String" DbType="NVarChar(10)" CanBeNull="true" />
<Column Name="Country" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
<Column Name="Phone" Type="System.String" DbType="NVarChar(24)" CanBeNull="true" />
<Column Name="Fax" Type="System.String" DbType="NVarChar(24)" CanBeNull="true" />
</ElementType>
</Function>
用sqlmetal对它做影射,生成dbml为
<Function Name="dbo.Get Customer And Orders" Method="GetCustomerAndOrders">
<Parameter Name="CustomerID" Parameter="customerID" Type="System.String" DbType="NChar(5)" />
<ElementType Name="GetCustomerAndOrdersResult1">
<Column Name="CustomerID" Type="System.String" DbType="NChar(5)" CanBeNull="true" />
<Column Name="CompanyName" Type="System.String" DbType="NVarChar(40)" CanBeNull="true" />
<Column Name="ContactName" Type="System.String" DbType="NVarChar(30)" CanBeNull="true" />
<Column Name="ContactTitle" Type="System.String" DbType="NVarChar(30)" CanBeNull="true" />
<Column Name="Address" Type="System.String" DbType="NVarChar(60)" CanBeNull="true" />
<Column Name="City" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
<Column Name="Region" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
<Column Name="PostalCode" Type="System.String" DbType="NVarChar(10)" CanBeNull="true" />
<Column Name="Country" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
<Column Name="Phone" Type="System.String" DbType="NVarChar(24)" CanBeNull="true" />
<Column Name="Fax" Type="System.String" DbType="NVarChar(24)" CanBeNull="true" />
</ElementType>
<ElementType Name="GetCustomerAndOrdersResult2">
<Column Name="OrderID" Type="System.Int32" DbType="Int" CanBeNull="true" />
<Column Name="CustomerID" Type="System.String" DbType="NChar(5)" CanBeNull="true" />
<Column Name="EmployeeID" Type="System.Int32" DbType="Int" CanBeNull="true" />
<Column Name="OrderDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
<Column Name="RequiredDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
<Column Name="ShippedDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
<Column Name="ShipVia" Type="System.Int32" DbType="Int" CanBeNull="true" />
<Column Name="Freight" Type="System.Decimal" DbType="Money" CanBeNull="true" />
<Column Name="ShipName" Type="System.String" DbType="NVarChar(40)" CanBeNull="true" />
<Column Name="ShipAddress" Type="System.String" DbType="NVarChar(60)" CanBeNull="true" />
<Column Name="ShipCity" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
<Column Name="ShipRegion" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
<Column Name="ShipPostalCode" Type="System.String" DbType="NVarChar(10)" CanBeNull="true" />
<Column Name="ShipCountry" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
</ElementType>
</Function>
仔细比较他们的区别哦。“好像名字不一样呢”。晕倒。看主要的。第一个只有一个ElementType子项,而第二个有2个。这个地方其实可以说是OR designer的一个bug。要想修改这个bug,需要更改一个设计,而推动更改设计,比较麻烦。但并不是不能改。如果你认为这个真的很需要,而且对你很重要,你更喜欢用or designer的话,我建议你去下面的社区发帖子。
http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=123&SiteID=1
要求更改此处的问题。因为,我已经无力推动他们修复该bug,ms更乐意听来自客户的声音,说不定你会成功的哦,还有奖励的哦。
这个sprocs准确的影射代码为
[Function(Name="dbo.Get Customer And Orders")]
[ResultType(typeof(GetCustomerAndOrdersResult1))]
[ResultType(typeof(GetCustomerAndOrdersResult2))]
public IMultipleResults GetCustomerAndOrders([Parameter(Name="CustomerID", DbType="NChar(5)")] string customerID)
CREATE PROCEDURE [dbo].[CustOrderTotal]
@CustomerID nchar(5),
@TotalSales money OUTPUT
AS
SELECT @TotalSales = SUM(OD.UNITPRICE*(1-OD.DISCOUNT) * OD.QUANTITY)
FROM ORDERS O, "ORDER DETAILS" OD
where O.CUSTOMERID = @CustomerID AND O.ORDERID = OD.ORDERID
其影射的code为
[Function(Name="dbo.CustOrderTotal")]
public int CustOrderTotal([Parameter(Name="CustomerID", DbType="NChar(5)")] string customerID, [Parameter(Name="TotalSales", DbType="Money")] ref System.Nullable<decimal> totalSales)
[Function(Name = "dbo.[Customers By City]")]
public ISingleResult<Customers_By_CityResult1> Customers_By_City([Parameter(DbType = "NVarChar(20)")] string param1)
public ISingleResult<Customers_By_CityResult1> Customers_By_City2(string para, out int returnValue)
DataClasses1DataContext db = new DataClasses1DataContext();
db.Log = Console.Out;
int returnValue = -1;
var q = db.Customers_By_City2("London",out returnValue);
Console.WriteLine(returnValue);
也可以使用result.GetParameterValue方法获取返回值。只是linq会检查影射函数的参数个数。这个使用起来比较麻烦。可以这么使用,比如,有一个sprocs,有2个参数,其中有一个out的参数。这个out的参数,可以不做任何操作。在影射后,修改其code。这两个参数的位标是从0开始,依次递增。其code本来为outParameter = ((System.Nullable<int>)(result.GetParameterValue(1))); 将其索引修改位为2,就是return value了。再大了又该抛了。
ps:招聘,我就趁机打个广告吧.呵呵。赴微软测试工程师
1, 计算机或软件,相关专业,本科或硕士以上。
2, 2年及2年以上工作经验。
3, 英语,听说读写流利。
4, 工作认真负责,学习能力强。
5, 精通c#1.1及c#2.0版本语言,对c#3.0有了解。
6, 精通算法。
7, 有Ado.Net 和Asp.Net的经验。技术好。
有意者投简历到guoan@126.com 谢谢
相关文章:
ps:
C# 3.0 入门系列(一)
C# 3.0入门系列(二)
C# 3.0入门系列(三)
C# 3.0入门系列(四)-之Select操作
C#3.0入门系列(五)-之Where操作
C#3.0入门系列(六)-之OrderBy操作
C#3.0入门系列(七)--之OR工具介绍
C#3.0入门系列(八)-之GroupBy操作
C#3.0入门系列(九)-之GroupBy操作
C#3.0入门系列(十)-之Join操作
C#3.0入门系列(十一)-之In, Like操作
C#3.0入门系列(十二)-Lambda表达式中Lifting
Linq To Sql进阶系列(一)-从映射讲起
Linq To Sql进阶系列(二)M:M关系
Linq To Sql进阶系列(三)CUD和Log
Linq To Sql进阶系列(四)User Define Function篇
Linq To Sql进阶系列(五)Store Procedure篇
TrackBack:/article/4785695.html
相关文章推荐
- [转]Linq To Sql进阶系列(一)-从映射讲起
- 1 Linq To Sql进阶系列
- Linq To Sql进阶系列(七)动态查询续及CLR与SQL在某些细节上的差别
- Linq To Sql进阶系列(一)-从映射讲起
- [转]Linq To Sql进阶系列(五)Store Procedure篇
- Linq To Sql进阶系列
- Linq To Sql进阶系列(六)用object的动态查询与保存log篇
- Linq To Sql进阶系列(七)动态查询续及CLR与SQL在某些细节上的差别
- .NET深入实战系列—Linq to Sql进阶
- [Linq To Sql进阶系列] 目录导航
- Linq To Sql进阶系列(二)M:M关系
- [转]Linq To Sql进阶系列(四)User Define Function篇
- Linq To Sql进阶系列(三)CUD和Log
- Linq To Sql进阶系列(六)用object的动态查询与保存log篇
- Linq To Sql进阶系列
- Linq To Sql进阶系列
- Linq To Sql进阶系列(三)CUD和Log
- Linq To Sql进阶系列(六)用object的动态查询与保存log篇
- [转]Linq To Sql进阶系列(七)动态查询续及CLR与SQL在某些细节上的差别
- Linq To Sql进阶系列(四)User Define Function篇