Effective C# (Covers C# 6.0), (includes Content Update Program): 50 Specific Ways to Improve Your C#, 3rd Edition By Bill Wagner 讀後心得
作者建議盡量使用 query 方式訪問查詢而非 method calls,但其實這部份見仁見智;本質上兩者轉譯後的語法是相同的(query 轉譯成 method calls)。以下提出一個在實務上容易發生的錯誤。
在 query 寫法中,不要串接自定義的方法;否則會造成執行錯誤(訪問資料庫時)。
範例:
var allEmployees = FindAllEmployees( );
// Find the first employees :
var earlyFolks = from e in allEmployees
where e.Classification == EmployeeType.Salary
where e.YearOfService > 20
where e.MonthlySalary < 4000
select e;
// Find the newest people :
var newest = from e in allEmployees
where e.Classification == EmployeeType.Salary
where e.YearOfService < 20
where e.MonthlySalary < 4000
select e;
這兩段查詢,可以很快發現兩者重覆的部分;依照 don't repeat yourself 原則,很自然的將重覆的查詢抽取出來寫成方法。
private bool LowPaidSalaried( Employee e ) =>
e.MonthlySalary < 4000 &&
e.Classification == EmployeeType.Salary;
var allEmployees = FindAllEmployees( );
// Factor out method :
var earlyFolks = from e in allEmployees
where LowPaidSalaried( e ) &&
e.YearOfService > 20
select e;
// Find the newest people :
var newest = from e in allEmployees
where LowPaidSalaried( e ) &&
e.YearOfService < 20
select e;
這樣的寫法在查詢皆在本機記憶體時可以正常運作,但若是需連結資料庫並回傳時就會出現 runtime error。原因在於編譯器會將 query 轉譯成 SQL 查詢語法,並在資料庫端執行;而包裝成方法的寫法會造成轉譯失敗。
比較好的實作方式,是將重覆的部分利用擴充方法提取出來;利用 IQueryable query 可組合的特性,讓客戶端自行串接之後的查詢邏輯一併在資料庫執行。
public static IQueryable<Employee> LowPaidSalariedFilter(
this IQueryable<Employee> sequence ) =>
from s in sequence
where s.Classification == EmployeeType.Salary &&
s.MonthlySalary < 4000
select s;
var allEmployees = FindAllEmployees( );
// Find the first employees :
var salaried = allEmployees.LowPaidSalariedFilter( );
var earlyFolks = from e in salaried
where e.YearOfService > 20
select e;
var newest = from e in salaried
where e.YearOfService < 20
select e;
結論:
1. query 與 method calls 本質上相同,使用時機端看開發者習慣。
2. 串接 query 或 method calls 時,不要在串接時呼叫自定義方法;此舉會造成轉換成 SQL 語法失敗。
1. query 與 method calls 本質上相同,使用時機端看開發者習慣。
2. 串接 query 或 method calls 時,不要在串接時呼叫自定義方法;此舉會造成轉換成 SQL 語法失敗。