我想創建一個通用Exists()命令類,它能夠爲任何LinqToSQL類的公共屬性(字段)的任何組合構造一個where子句表)在我的datacontext(數據庫)。Expression.Lambda <Func<T,bool>>說'T'找不到
如果根據MSDN的代碼片段編寫了以下代碼,並且發現我無法成功運行代碼,除非我明確聲明Expression.Lambda參數的實體類型(在本例中爲MyApp.Data.Organization) Expression.Call語句。
換句話說,
Expression.Lambda<Func<tblType,bool>>(predBody, new ParameterExpression[] { pe }));
不工作,但是,
Expression.Lambda<Func<MyApp.Data.Organization,bool>>(predBody, new ParameterExpression[] { pe }));
確實工作。我想要類似前者的東西,所以這個方法在我的數據上下文中對所有的LinqToSQL類都是通用的。
我已驗證Expression.Call語句之前的所有代碼均正常工作,並且會生成正確的謂詞。我需要更改什麼以保持參數類型的泛型,以便相同的代碼可以用於數據上下文中的任何LinqToSQL類?
修正爲清晰度 看來我使用T作爲變量是令人困惑的事情。下面是修改後的代碼:
OrganizationCriteria criteria = new OrganizationCriteria { OrganizationId = 2 };
using (var ctx = ContextManager<MyApp.Data.MyAppDataContext>.GetManager(myConnectionString, false)) {
IQueryable tbl = ctx.DataContext.GetTable(criteria.EntityType).AsQueryable();
Type tblType = tbl.ElementType;
ParameterExpression pe = Expression.Parameter(tblType, "Item");
Expression left;
Expression right;
Expression prev = null;
Expression curr = null;
Expression predBody = null;
foreach (KeyValuePair<string, object> kvp in criteria.StateBag) {
prev = curr;
object val = kvp.Value;
if (val is System.String) {
left = Expression.Call(pe, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes));
right = Expression.Constant(kvp.Value.ToString());
}
else {
left = Expression.Property(pe, tblType.GetProperty(kvp.Key));
right = Expression.Constant(kvp.Value, tblType.GetProperty(kvp.Key).PropertyType);
}
curr = Expression.Equal(left, right);
if (prev != null) {
predBody = Expression.AndAlso(prev, curr);
}
else {
predBody = curr;
}
}
MethodCallExpression whereCall = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { tblType },
tbl.Expression,
Expression.Lambda<Func<tblType,bool>>(predBody, new ParameterExpression[] { pe }));
var results = tbl.Provider.CreateQuery(whereCall);
}
那麼,哪裏來* T來自? – BoltClock 2012-01-10 19:06:21
@BoltClock他想創建一個接受類型參數「T」的方法,因此在創建表達式時不能指定特定的「T」。 – CodesInChaos 2012-01-10 19:07:38
答案是使用Expression.Lambda()的非泛型重載。因此,替換: Expression.Lambda>(predBody,新ParameterExpression [] {PE}) 與 Expression.Lambda(predBody,新ParameterExpression [] {PE}) 做訣竅, –
FuzzyCoder
2012-01-10 20:29:29