Linq To Sql进阶系列(四)User Define Function篇
[1] 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篇
[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在某些细节上的差别
4 TVF
返回一个table 的UDF称为TVF.看下面例子
CREATE FUNCTION [dbo].[ProductsUnderThisUnitPrice]
(@price Money
)
RETURNS TABLE
AS
RETURN
SELECT *
FROM Products as P
Where p.UnitPrice < @price
TVF在sql中支持from,join,union等操作。同样,这些操作在Linq To Sql中一样支持。该TVF的dbml为:
<Function Name="dbo.ProductsUnderThisUnitPrice" Method="ProductsUnderThisUnitPrice"
IsComposable="true">
<Parameter Name="price" Type="System.Decimal" DbType="Money" />
<ElementType Name="ProductsUnderThisUnitPriceResult">
<Column Name="ProductID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
<Column Name="ProductName" Type="System.String" DbType="NVarChar(40) NOT NULL"
CanBeNull="false" />
<Column Name="SupplierID" Type="System.Int32" DbType="Int" CanBeNull="true" />
<Column Name="CategoryID" Type="System.Int32" DbType="Int" CanBeNull="true" />
<Column Name="QuantityPerUnit" Type="System.String" DbType="NVarChar(20)"
CanBeNull="true" />
<Column Name="UnitPrice" Type="System.Decimal" DbType="Money" CanBeNull="true" />
<Column Name="UnitsInStock" Type="System.Int16" DbType="SmallInt" CanBeNull="true" />
<Column Name="UnitsOnOrder" Type="System.Int16" DbType="SmallInt" CanBeNull="true" />
<Column Name="ReorderLevel" Type="System.Int16" DbType="SmallInt" CanBeNull="true" />
<Column Name="Discontinued" Type="System.Boolean" DbType="Bit NOT NULL"
CanBeNull="false" />
</ElementType>
</Function>
IsComposable="true">
<Parameter Name="price" Type="System.Decimal" DbType="Money" />
<ElementType Name="ProductsUnderThisUnitPriceResult">
<Column Name="ProductID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
<Column Name="ProductName" Type="System.String" DbType="NVarChar(40) NOT NULL"
CanBeNull="false" />
<Column Name="SupplierID" Type="System.Int32" DbType="Int" CanBeNull="true" />
<Column Name="CategoryID" Type="System.Int32" DbType="Int" CanBeNull="true" />
<Column Name="QuantityPerUnit" Type="System.String" DbType="NVarChar(20)"
CanBeNull="true" />
<Column Name="UnitPrice" Type="System.Decimal" DbType="Money" CanBeNull="true" />
<Column Name="UnitsInStock" Type="System.Int16" DbType="SmallInt" CanBeNull="true" />
<Column Name="UnitsOnOrder" Type="System.Int16" DbType="SmallInt" CanBeNull="true" />
<Column Name="ReorderLevel" Type="System.Int16" DbType="SmallInt" CanBeNull="true" />
<Column Name="Discontinued" Type="System.Boolean" DbType="Bit NOT NULL"
CanBeNull="false" />
</ElementType>
</Function>
ElementType子项说明了其返回一个table.映射为类的名称为ProductsUnderThisUnitPriceResult。其映射的code中,不光是一个函数,还有一个对应的返回类。当然,这个返回类的定义,可以由用户自己指定。此处不讲。我们使用默认的类。我们先来看一个from的例子
var q = from p in db.ProductsUnderThisUnitPrice(10.25M)
select p;
select p;
你可以就把该udf当作一个普通的表来使用。再举一个join操作Linq To Sql的例子
var q = from c in db.Categories
join p in db.ProductsUnderThisUnitPrice(8.50M) on c.CategoryID equals
p.CategoryID into prods
from p in prods
select new {c.CategoryID, c.CategoryName, p.ProductName, p.UnitPrice};
join p in db.ProductsUnderThisUnitPrice(8.50M) on c.CategoryID equals
p.CategoryID into prods
from p in prods
select new {c.CategoryID, c.CategoryName, p.ProductName, p.UnitPrice};
因为,sql中支持TVF的in-line操作,所以Linq To Sql完全支持其对等的操作。他们所生成的sql语句不再列出。
总结:
通过本文,我们可以看出Linq To Sql完全融入了Sql中UDF,包括对其内联操作的支持。对于某些特殊需求,用户可以手工将函数映射为code,但这并不说明,任何函数都适用。