Linq To Sql进阶系列(四)User Define Function篇
[2] Linq To Sql进阶系列(四)User Define Function篇
[3] Linq To Sql进阶系列(四)User Define Function篇
[4] Linq To Sql进阶系列(四)User Define Function篇
系列文章导航:
Linq To Sql进阶系列(四)User Define Function篇
Linq To Sql进阶系列(五)Store Procedure篇
Linq To Sql进阶系列(六)用object的动态查询与保存log篇
Linq To Sql进阶系列(七)动态查询续及CLR与SQL在某些细节上的差别
在这里,笔者将带着大家开始习惯用dbml来维护数据库的映射,而不是code.在beta2发布后,有人很快就能发现mapping code无法编译了。因为接口改动了。好,回归正题。
无论是UDF还是Sprocs都会被映射为Function. 而IsComposable="true"是UDF独有的一个特性,是标志UDF身份的,Linq用它来区别Sprocs和UDF。这个字段说明,该函数是支持内联查询的。Name则是其在数据库中的名称。再来看其生成的code.
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(constant);
再就让我们来看几个内联的查询的。所谓内联(in-line),就是说,你可以把UDF当作一个表(TVF),或一个变量(SVF),写在sql语句里。比如:
WHERE t0.UnitPrice = dbo.MinUnitPriceByCategory(t0.CategoryID)
在这个sql语句中,就调用了上面那个UDF。同样Linq To Sql也支持这样操作。可以写为
where p.UnitPrice == db.MinUnitPriceByCategory(p.CategoryID)
select p;
大家可以看看其生成的Sql是不是和上面的一样。再举一个UDF的例子
(@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
计算某类产品的单价总和。这次,我们在select字句里调用它
FROM Categories
其同样功能的Linq语句为:
select new {c.CategoryID, TotalUnitPrice = db.TotalProductUnitPriceByCategory(c.CategoryID)};
其实,对于SVF,可以放在除from等与table有关语句之外的任何地方。比如Order by, Group by等。同样Linq全部支持。如例
where p.UnitsOnOrder >= db.SVF(p.UnitsInStock)
group p by db.SVF(p.CategoryID) into g
order by db.SVF(g.Key)
select db.SVF(g.Key);
当然,这个纯粹是给个例子,并没有太多实际意义。