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在某些细节上的差别
3,系统函数的映射
目前为止,无论是OR designer还是SqlMetal均不支持对系统函数的映射。笔者也只是尝试着,手工映射,并成功调用。我们拿Var函数举例。Var是求方差。让我们来模仿上面那个dbml来改写自己的dbml。我们将要多money类型做求var值。并且希望能够调用sql server提供的var函数。那就需要我们将映射的名称改成var,并且改动参数和返回值类型。其最后的dbml为:
<Function Name="Var" Method="Var" IsComposable="true">
<Parameter Name="para" Type="System.Decimal" DbType="Money" />
<Return Type="System.Decimal" />
</Function>
<Parameter Name="para" Type="System.Decimal" DbType="Money" />
<Return Type="System.Decimal" />
</Function>
其生成的code为:
[Function(IsComposable=true)]
public System.Nullable<decimal> Var([Parameter(DbType="Money")] System.Nullable<decimal> para)
{
return ((System.Nullable<decimal>)(this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), para).ReturnValue));
}
public System.Nullable<decimal> Var([Parameter(DbType="Money")] System.Nullable<decimal> para)
{
return ((System.Nullable<decimal>)(this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), para).ReturnValue));
}
将该方法,放在DataContext的一个partial类中,我们并不想破坏其原来的mapping 文件,所以,单独放在一个partial类中。而后,我们尝试着Linq To Sql中调用该函数
var q = (from p in db.Products
select db.Var(p.UnitPrice)).ToList();
select db.Var(p.UnitPrice)).ToList();
其生成的sql为
SELECT CONVERT(Decimal(29,4),Var([t0].[UnitPrice])) AS [value]
FROM [dbo].[Products] AS [t0]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel
FROM [dbo].[Products] AS [t0]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel
我们就这样骗过了Linq To Sql的Run-Time。 成功调用sql server提供var函数。再比如,有人习惯于用NEWID()随机排序,达到取随机记录的目的。其原始sql为:
SELECT TOP 10 * FROM TABLE1 ORDER BY NEWID();
那用Linq To Sql该如何来做这个事情呢?不好意思,目前还不支持对系统函数的映射。那就手工来做吧。
因为NewId返回uniqueidentifier类型,我们将这个函数定义为
[Function(Name = "NewID", IsComposable = true)]
public Guid NewID()
{
return ((Guid)(this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod()))).ReturnValue));
}
public Guid NewID()
{
return ((Guid)(this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod()))).ReturnValue));
}
调用时,可以
var q = db.Table1.OrderBy(p => db.NewID()).Take(10).ToList();
这只是一个小技巧,并不说明,所有的函数都可以这么做。