所以,我使用 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;
}