设想:
我有一个 JavaScript 库,它使用服务器端挂钩处理表的分页/排序/搜索。我已经连接了服务器端 JSON 调用,创建了一个模型绑定器,将传入的值转换为可用的请求对象,现在我正在尝试实现搜索。
通过请求对象,我可以访问要排序的列列表。我正在尝试编写一个通用函数,该函数将允许任何表传入其列,并为每列和搜索值生成 .Where 调用。
目前的方法是获取字符串属性名称,使用反射获取实际值,然后将其与搜索参数进行比较。我正在尝试的非常粗略的方法是:
public static IQueryable GetSearchClause(IQueryable<object> query, DataTablesPageRequest pageRequest)
{
var columns = pageRequest.ColumnNames.Split(',');
for (var i = 0; i < pageRequest.Searchable.Count; ++i)
{
if (pageRequest.Searchable[i])
{
var column = columns[i];
var test = query.Where(x => x.GetType().GetProperty(column)
.GetValue(query.Select(z => z.GetType()), null)
.Equals("test"));
}
}
return query;
}
当我查看生成的“测试”对象时,我得到了一个非常不愉快的堆栈跟踪:
at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitMethodCallExpression(MethodCallExpression expression)
at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitExpression(Expression expression)
at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.Visit(Expression expression, VisitorParameters parameters)
at NHibernate.Linq.Visitors.QueryModelVisitor.VisitWhereClause(WhereClause whereClause, QueryModel queryModel, Int32 index)
at Remotion.Linq.Clauses.WhereClause.Accept(IQueryModelVisitor visitor, QueryModel queryModel, Int32 index)
at Remotion.Linq.QueryModelVisitorBase.VisitBodyClauses(ObservableCollection`1 bodyClauses, QueryModel queryModel)
at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)
at NHibernate.Linq.Visitors.QueryModelVisitor.Visit()
at NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery(QueryModel queryModel, VisitorParameters parameters, Boolean root)
at NHibernate.Linq.NhLinqExpression.Translate(ISessionFactoryImplementor sessionFactory)
at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(String queryIdentifier, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.HQLExpressionQueryPlan.CreateTranslators(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters)
at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)
at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)
at NHibernate.Linq.DefaultQueryProvider.PrepareQuery(Expression expression, IQuery& query, NhLinqExpression& nhQuery)
at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
at NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)
at Remotion.Linq.QueryableBase`1.GetEnumerator()
at System.Linq.SystemCore_EnumerableDebugView`1.get_Items()
我什至可以用这种技术完成我想要做的事情,还是我真的应该使用逐实体方法,因为我会提前知道要搜索哪些列(并跳过整个反射位)?