因此,我使用MVC,并且正在使用名为DataTable的JS库来显示数据。好吧,我正在使用服务器的AJAX响应将数据馈送到表中。因为我将大量使用DataTable,所以我决定创建一个模型,该模型可让我快速创建实例并将数据反馈给客户端。我已经解决了所有这些问题,但是搜索存在一个问题。我正在使用Expression.Call()
在运行时构建查询,以从数据库中收集数据。我正在使用泛型,因为我要用DataTable显示许多不同的模型,而创建该模型是为了尽量减少我的代码行。
好吧,有时呼叫将花费大约一秒钟来完成并返回给客户端。并不可怕,但是我相信应该有一种方法来改善这段时间。我考虑过将从Expression.Call()
中生成的方法存储在变量中,然后再调用它。唯一的问题是,使用缓存的表达式后,我的变量未定义。我必须在开始时为我的方法提供一个参数,这会导致问题。
此外,我对使用System.Reflection和泛型还比较陌生。如果有更好的使用方法,请链接到文章。
错误是因为变量'item'存在但在此上下文中未定义。
private static readonly var CachedSearchQuery = new Dictionary<string, MethodCallExpression>();
private Expression<Func<T, bool>> GenerateSearchValues()
{
if (search == null || search.value == null)
return null;
Expression<Func<T, bool>> body = null;
ParameterExpression param = Expression.Parameter(typeof(T), "item");
columns.ForEach(c =>
{
if (c.searchable)
{
var prop = Expression.PropertyOrField(param, c.data);
var containMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var toLowerMethod = typeof(string).GetMethod("ToLower", Type.EmptyTypes);
var toString = typeof(string).GetMethod("ToString", Type.EmptyTypes);
var cont = Expression.Constant(search.value, typeof(string));
Expression<Func<T, bool>> containExpr = null;
if(!CachedSearchQuery.Contains(c.data)) {
try
{
CachedSearchQuery[c.data] = Expression.Call(prop, toLowerMethod);
containExpr = Expression.Lambda<Func<T, bool>> (
Expression.Call(
CachedSearchQuery[c.data],
containMethod,
cont),
param);
}
catch/*(ArgumentException e)*/
{
toString = typeof(object).GetMethod("ToString", Type.EmptyTypes);
CachedSearchQuery[c.data] =
Expression.Call(
Expression.Call(prop, toLowerMethod),
toString);
containExpr = Expression.Lambda<Func<T, bool>>(
Expression.Call(
CachedSearchQuery[c.data],
containMethod,
cont),
param);
}
}
else
{
containExpr =
Expression.Lambda<Func<T, bool>>(
Expression.Call(
CachedSearchQuery[c.data],
containMethod,
cont),
param);
}
if (containExpr == null)
return;
if (body == null)
body = containExpr;
else
{
body = Expression.Lambda<Func<T, bool>>
(
Expression.Or(
body,
Expression.Invoke(
containExpr,
body.Parameters.Cast<Expression>()
)
),
body.Parameters);
}
}
});
return body;
}