11-9. 在LINQ中使用規範函數問題想在一個LINQ查詢中使用規範函數解決方案假設我們已經有一個影片租賃(MovieRental )實體,它保存某個影片什麼時候租出及還回來,以及滯納金等,如Figure 11-9. 所示:Figure 11-9. The MovieRental entity t...
11-9. 在LINQ中使用規範函數
問題
想在一個LINQ查詢中使用規範函數
解決方案
假設我們已經有一個影片租賃(MovieRental )實體,它保存某個影片什麼時候租出及還回來,以及滯納金等,如Figure 11-9. 所示:
Figure 11-9. The MovieRental entity that has the dates for a rental period along with any late fees
我們想取得所有租期超過10天的影片
如何創建和使用查詢,如Listing 11-16所示:
Listing 11-16. Retrieving the Late Movies using the DateDiff() Function
class Program
{
static void Main(string[] args)
{
RunExample();
}
private static void RunExample()
{
using (var context=new EFRecipesEntities())
{
var mr1 = new MovieRental
{
Title = "A Day in the Life",
RentalDate = DateTime.Parse("2/19/2013"),
ReturnedDate = DateTime.Parse("3/4/2013"),
LateFees = 3M
};
var mr2 = new MovieRental
{
Title = "The Shortest Yard",
RentalDate = DateTime.Parse("3/15/2013"),
ReturnedDate = DateTime.Parse("3/20/2013"),
LateFees = 0M
};
var mr3 = new MovieRental
{
Title = "Jim's Story",
RentalDate = DateTime.Parse("3/2/2013"),
ReturnedDate = DateTime.Parse("3/19/2013"),
LateFees = 3M
};
context.MovieRentals.Add(mr1);
context.MovieRentals.Add(mr2);
context.MovieRentals.Add(mr3);
context.SaveChanges();
}
using (var context = new EFRecipesEntities())
{
Console.WriteLine("Movie rentals late returns");
Console.WriteLine("==========================");
var late = from r in context.MovieRentals
where DbFunctions.DiffDays(r.RentalDate, r.ReturnedDate) > 10
select r;
foreach (var rental in late)
{
Console.WriteLine("{0} was {1} days late, fee: {2}", rental.Title,
(rental.ReturnedDate - rental.RentalDate).Days - 10,
rental.LateFees.ToString("C"));
}
}
}
}
上述Listing 11-16代碼輸出結果如下:
Movie rentals late returns
==========================
A Day in the Life was 3 days late, fee: $3.00
Jim's Story was 7 days late, fee: $3.00
它是如何工作的?
定義在EF里的規範函數, 它可以不被數據源所知道,而且能被數據提供器支持.規範函數返回的數據類型是根據實體數據模型的類型定義的.
在本小節里,我們使用DiffDays() 函數來計算兩個日期的所差的天數,由於DiffDays()是一個規範函數,所以它能被數據所有提供者執行.
最佳實踐
你可能會問自己“什麼時候應該用實體函數?”. EF提供者把一些表達式翻譯成規範函數, 但是這種翻譯能力是有限的.不是每個運行時方法都能翻譯成相應的規範函數,這裡是一些最佳實踐,如果可以翻譯,那麼就使用它,這樣能使代碼易讀.如果不能翻譯,那麼就明確地使用EntityFunction類來調用規範函數,就像下列的代碼片段:
var laterentals = from r in context.MovieRentals
where (r.ReturnedDate - r.RentalDate).Days > 10
select r;
上面這句,不能翻譯成規範函數,所以你應該使用下列這句:
var laterentals = from r in context.MovieRentals
where EntityFunctions.DiffDays(r.RentalDate,
r.ReturnedDate) > 10
select r;