Итак, я использую MVC и использую библиотеку JS с именем DataTable для отображения данных. Что ж, я передаю данные в таблицу, используя ответ AJAX с сервера. Поскольку я буду часто использовать DataTable, я решил создать модель, которая позволит мне быстро создать экземпляр и передать данные клиенту. У меня все это решено, однако у меня есть одна проблема с поиском. Я использую Expression.Call()
для создания запроса в RunTime для сбора данных из моей базы данных. Я работаю с дженериками, потому что у меня есть много разных моделей, которые я отображаю с помощью 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;
}