技术开发 频道

Linq To Sql进阶系列(四)User Define Function篇


【IT168技术文档】
  1,UDF 简介
  UDF可以分为两中类型。一种为Scalar Valued Function,简称为SVF,是返回值类型的UDF. 另一种为Table Valued Function 简称为TVF,是返回一个table的UDF. 人们通常喜欢拿UDF和Store Procedure做比较。其实,他们各有千秋。UDF最多只能返回一个RowSet,而Store Procedure可以是多个。Store Procedure支持CUD操作,而UDF不支持。但是UDF在sql 中支持内联查询,这个又是Sprocs所不能及的。因此Linq To Sql 也支持UDF的内联查询。
  2,SVF
  看下面这个例子。返回某个类别产品最小的单元价格。
CREATE FUNCTION [dbo].[MinUnitPriceByCategory] (@categoryID INT ) RETURNS Money AS BEGIN -- Declare the return variable here DECLARE @ResultVar Money -- Add the T-SQL statements to compute the return value here SELECT @ResultVar = MIN(p.UnitPrice) FROM Products as p WHERE p.CategoryID = @categoryID -- Return the result of the function RETURN @ResultVar END
  用OR Designer(请参考OR工具介绍 )将其映射为Dbml。如下
<Function Name="dbo.MinUnitPriceByCategory" Method="MinUnitPriceByCategory" IsComposable="true"> <Parameter Name="categoryID" Type="System.Int32" DbType="Int" /> <Return Type="System.Decimal" /> </Function>
  在这里,笔者将带着大家开始习惯用dbml来维护数据库的映射,而不是code.在beta2发布后,有人很快就能发现mapping code无法编译了。因为接口改动了。好,回归正题。
  无论是UDF还是Sprocs都会被映射为Function. 而IsComposable="true"是UDF独有的一个特性,是标志UDF身份的,Linq用它来区别Sprocs和UDF。这个字段说明,该函数是支持内联查询的。Name则是其在数据库中的名称。再来看其生成的code.
[Function(Name="dbo.MinUnitPriceByCategory", IsComposable=true)] public System.Nullable<decimal> MinUnitPriceByCategory([Parameter(DbType="Int")] System.Nullable<int> categoryID) { return ((System.Nullable<decimal>)(this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), categoryID).ReturnValue)); }
  Linq To Sql将Sprocs和UDF映射成DataContext类里的方法的形式,这样用户就可以像调用函数那样,调用该UDF。因为这个例子是SVF,所以,返回decimal类型的值。再来看它的应用。刚才说过,可以像函数那样调用它。比如:
int result = db.IntSVF(variable); int result = db.IntSVF(constant);
  再就让我们来看几个内联的查询的。所谓内联(in-line),就是说,你可以把UDF当作一个表(TVF),或一个变量(SVF),写在sql语句里。比如:
SELECT * FROM Products AS t0 WHERE t0.UnitPrice = dbo.MinUnitPriceByCategory(t0.CategoryID)
  在这个sql语句中,就调用了上面那个UDF。同样Linq To Sql也支持这样操作。可以写为
var q = from p in db.Products where p.UnitPrice == db.MinUnitPriceByCategory(p.CategoryID) select p;
  大家可以看看其生成的Sql是不是和上面的一样。再举一个UDF的例子
CREATE FUNCTION [dbo].[TotalProductUnitPriceByCategory] (@categoryID int) RETURNS Money AS BEGIN -- Declare the return variable here DECLARE @ResultVar Money -- Add the T-SQL statements to compute the return value here SELECT @ResultVar = (Select SUM(UnitPrice) from Products where CategoryID = @categoryID) -- Return the result of the function RETURN @ResultVar END
0
相关文章