我想创建一个通用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