備注:本文的源代碼例子,使用的數據庫為SQL Server 2005下的Northwind示范數據庫,同時為相關表建立了TimeStamp列。
LINQ是Visual Studio 2008中提供的一系列新特性,用以擴展C#或者Visual Basic語言,提供了強有力的查詢能力。作為LINQ的組成部分,LINQ to SQL提供了將關系數據作為對象處理的運行時架構。從某種程度上說,它相當於是微軟提供的類似於NHibernate和Castle之類的ORM工具或框架。當我們需要對數據庫進行訪問時,LINQ to SQL常常會成為我們的首選。
在LINQ to SQL中,關系數據庫數據模型中的所有變量都是強類型的,它提供了編譯時驗證以及智能感知等優點。我們可以使用查詢表達式(包括查詢語法和方法語法)從數據庫中獲取數據。
然而,強類型並不利於對數據操作進行抽象,因此,開發人員就不得不為每個實體對象定義特定的類,從而導致大量的重復代碼。如果我們可以實現一個共同的基類,封裝公共的數據操作,例如Select、Where、Add、Update和Delete,這對於開發N層應用程序而言,是非常有用的。
所幸,利用泛型可以幫助我們實現這一目標。方法是調用DataContext的GetTable<T>()方法。例如,我們可以實現Where方法,通過傳遞一個Lambda表達式找到我們希望獲得的結果:
public IList<TEntity> Where(Func<TEntity, bool> predicate)
{
InitDataContext();
return m_context.GetTable<TEntity>().Where(predicate).ToList<TEntity>();
}
這很簡單,我們甚至可以利用動態查詢,暴露一些方法去接收條件表達式:
public static class DynamicQueryable
{
public static IQueryable<T> Where<T>(this IQueryable<T> source, string predicate, params object[] values)
{
return (IQueryable<T>)Where((IQueryable)source, predicate, values);
}
public static IQueryable Where(this IQueryable source, string predicate, params object[] values)
{
if (source == null) throw new ArgumentNullException("source");
if (predicate == null) throw new ArgumentNullException("predicate");
LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, typeof(bool), predicate, values);
return source.Provider.CreateQuery(
Expression.Call(
typeof(Queryable), "Where",
new Type[] { source.ElementType },
source.Expression, Expression.Quote(lambda)));
}
}
public IList<TEntity> Where(string predicate, params object[] values)
{
InitDataContext();
return m_context.GetTable<TEntity>().Where(predicate, values).ToList<TEntity>();
}