1
方案与列工作:NHibernate的,通过反射
我有一个处理表的寻呼/排序/搜索,与服务器端钩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()
我能做到,甚至我试图用这种技术,还是应该真正使用每个实体的方法,因为我会提前知道要搜索哪些列(并跳过整个反射位)?
你能使用ICriteria吗?那么你不需要任何反射,只需使用属性名称即可。 – dotjoe 2012-08-06 14:47:59
尚未使用IC标准 - 但看起来更容易一些。我会稍微想一下。既然你问我是否可以使用它...有什么理由我不想使用它?对于您在NH中编写查询的方式,我仍然有点困惑;比另一个更受欢迎? – heyseuss 2012-08-06 14:54:02
只是不同的工具...我总是使用QueryOver(建立在ICriteria之上),因为它具有最多的NH功能。我问的唯一理由是如果有人玩政治,只让你使用linq(IQueryable)接口。 – dotjoe 2012-08-06 15:38:06