如果你想要一個通用的方法,讓你指定任何表和任何謂詞的記錄,那麼你真的不能比內建的Where<T>(...)
和(如其他人已經指出的)更好擴展方法。然後
您的代碼看起來像這樣:
var result = _gam.PAC.Where(pac => pac.CODI_PAC == codiPac).FirstOrDefault();
// OR
var result = _gam.PAC.FirstOrDefault(pac => pac.CODI_PAC == codiPac);
你能得到那麼最好的,寫自己的泛型方法,會是這樣:
public T FirstOrDefault<T>(IQueryable<T> source,
Expression<Func<T, bool>> predicate)
{
return source.Where(predicate).FirstOrDefault();
// OR
// return source.FirstOrDefault(predicate);
}
而這其實只是多餘的。尤其是當你調用的代碼將實際上不再使用輔助方法:
var result = FirstOrDefault(_gam.PAC, pac => pac.CODI_PAC == codiPac);
// versus
var result = _gam.PAC.FirstOrDefault(pac => pac.CODI_PAC == codiPac);
而且更糟的是,你的代碼不再使用流暢,組合的語法。這隻會使可讀性和維護更加困難。
如果你堅持使用IQueryable<T>
擴展方法,那麼你可以做的組成是這樣的:這裏要注意
var result = _gam.PAC
.Where(pac => pac.CODI_PAC == codiPac)
.Where(pac => pac.SomeOtherProperty == someOtherValue)
.FirstOrDefault();
// OR
var result = (from pac in _gam.PAC
where pac.CODI_PAC == codiPac
where pac.SomeOtherProperty == someOtherValue
select pac).FirstOrDefault();
其中很重要的一點是,在IQueryable<T>.Where<T>(...)
擴展方法的predicate
參數是Expression<Func<T, bool>>
類型。這允許IQueryable<T>
提供程序在返回結果之前的最後一刻構建本機SQL(或其他本地提供程序查詢)。
不使用Expression<Func<T, bool>>
意味着你的查詢會是這樣的等價物:
var result =
_gam.PAC
.ToArray()
.Where(pac => pac.CODI_PAC == codiPac)
.FirstOrDefault();
而這將意味着該查詢將從「PAC」表中加載所有記錄到內存中,選擇第一過濾結果之前和拋出其餘的結果。
的底線是,通過使通用的輔助方法,你是重寫現有的框架代碼並打開自己性能和維護問題同時減少代碼的可讀性。
我希望這會有所幫助。
你能告訴我,_gam是什麼嗎? – 2011-05-04 07:48:58
你在使用Entity Framework嗎? LINQ2SQL?還有別的嗎? – 2011-05-04 08:25:13
我認爲Where()和FirstOrDefault()擴展方法已經足夠滿足您的需要 – 2011-05-04 09:01:36