LINQ to SQL-在Where條件中使用getdate()
4 |
來個LINQ to SQL機車考題。
有一SQL資料表如下:
請問,若不用DataContext.ExecuteQuery(),有無可能使用LINQ語法轉換出如下的SQL指令?
SELECT COUNT(*) FROM Member
WHERE RegTime < GETDATE() AND REVERSE(UserName) = Code
我本來一直以為這種夾雜T-SQL函數的查詢條件,ExecuteQuery應是唯一解。今天查到一篇神奇的文章,才知道原來透過FunctionAttribute宣告,要搞出以下的LINQ寫法也是可能的:
var q = from o in db.Members
where o.RegTime > db.GetDate() &&
db.Reverse(o.UserName) == o.Code
select o;
方法是加外新增一個cs檔案,在其中宣告DataContext的partial class,加入以下兩個Method:
using System;
using System.Data.Linq.Mapping;
using System.Reflection;
namespace LinqTestBed
{
partial class PlayGroundDataContext : System.Data.Linq.DataContext
{
//REF: http://bit.ly/9l6LDz
[Function(Name = "GetDate", IsComposable = true)]
public DateTime GetDate()
{
MethodInfo mi = MethodBase.GetCurrentMethod() as MethodInfo;
return (DateTime)this.ExecuteMethodCall(this, mi,
new object[] { }).ReturnValue;
}
[Function(Name = "Reverse", IsComposable = true)]
public string Reverse(string str)
{
MethodInfo mi = MethodBase.GetCurrentMethod() as MethodInfo;
return (string)this.ExecuteMethodCall(this, mi,
new object[] { str }).ReturnValue;
}
}
}
如此,上述LINQ語法就會被轉換以下的T-SQL指令,很酷吧!!
SELECT * AS [value]
FROM [dbo].[Member] AS [t0]
WHERE ([t0].[RegTime] > GetDate()) AND (Reverse([t0].[UserName]) = [t0].[Code])
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.4926
FROM [dbo].[Member] AS [t0]
WHERE ([t0].[RegTime] > GetDate()) AND (Reverse([t0].[UserName]) = [t0].[Code])
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.4926
Comments
# by hectorlee369
缺點是每次要re-gen時,code都會消失 ... 好在有版控, 所以花點時間copy回來即可
# by Jeffrey
to hectorlee369, 上述的Code並不是加在自動產生的*.designer.cs裡,而是另外新增一個.cs,用partial class的方法加掛這兩個方法,這樣就不用怕re-gen時Code會消失囉!
# by jlin0502
您好, 在下新增一個.cs的檔案後. 在compile時會出現 "'System.Data.Linq.DataContext' 不包含使用 '0' 引數的建構函式" 錯誤. 不曉得問題出在哪裡呢?該如何解決?
# by Jeffrey
to jlin0502, 該錯誤的英文原文是"System.Data.Linq.DataContext' does not contain a constructor that takes '0' arguments",查了一下類似的案例,我猜是你在宣告class PlayGroundDataContext加入額外方法時,忘了加上"partial"關鍵字所造成的。