System.Reflection:存储表达式以备后用

时间:2019-07-10 00:14:23

标签: c# generics system.reflection

因此,我使用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;
        }

0 个答案:

没有答案