不支持NHibernate指定的方法

本文关键字:方法 NHibernate 不支持 | 更新日期: 2023-09-27 18:15:03

我开发了web应用程序,使用s# arpLite来构建一个查询,从许多表中获取列表。使用NHibernate版本3.3.1.4000

我得到了一个错误从应用程序时,它的运行时间,如

<>之前NHibernate体系。NotSupportedException指定的方法不支持。{Name = "PolymorphicQuerySourceDetector" FullName = "NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector"}在NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector。GetClassName (IASTNode querySource)在NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector。过程(IASTNode树)在NHibernate.Hql.Ast.ANTLR.AstPolymorphicProcessor.Process ()在NHibernate.Hql.Ast.ANTLR.AstPolymorphicProcessor。进程(IASTNode ast, ISessionFactoryImplementor factory)在NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory。CreateQueryTranslators(IASTNode ast, String queryIdentifier, String collectionRole, Boolean shallow, dictionary ' 2过滤器,ISessionFactoryImplementor factory)在NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory。CreateQueryTranslators(String queryIdentifier, IQueryExpression queryExpression, String collectionRole, Boolean shallow, dictionary ' 2 filters, ISessionFactoryImplementor factory)在NHibernate.Engine.Query.HQLExpressionQueryPlan。创建翻译(String expressionStr, IQueryExpression, queryExpression, String collectionRole, Boolean shallow, dictionary ' 2 enabledFilters, ISessionFactoryImplementor factory)在NHibernate.Engine.Query.HQLExpressionQueryPlan . .(字符串expressionStr, queryExpression, queryExpression, String collectionRole, Boolean shallow, dictionary ' 2 enabledFilters, ISessionFactoryImplementor factory)在NHibernate.Engine.Query.HQLExpressionQueryPlan . .(字符串expressionStr, queryExpression, queryExpression, Boolean shallow, dictionary ' 2)在NHibernate.Engine.Query.QueryPlanCache。getthqlqueryplan (queryExpression queryExpression, Boolean shallow, dictionary ' 2 enabledFilters)在NHibernate.Impl.AbstractSessionImpl。GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)在NHibernate.Impl.AbstractSessionImpl。CreateQuery (IQueryExpression queryExpression)在NHibernate.Linq.DefaultQueryProvider。PrepareQuery(Expression Expression, iquery&query, NhLinqExpression& nhQuery)在NHibernate.Linq.DefaultQueryProvider。执行表达式(表达式)在NHibernate.Linq.DefaultQueryProvider。执行[TResult](表达式表达)1. Remotion.Linq.QueryableBase"getenumerator ()在System.Collections.Generic.List"1 . .男星(IEnumerable 1组)在System.Linq.Enumerable。ToList [TSource] (IEnumerable ' 1源)在EzLife.Tasks.EmployeeCudTasks。GetEmployees(列表' 1 listSkill,列表' 1 listDepartment,列表' 1 listAssignment, String searchTerm, String jobtitle, String tier, String competency, Nullable ' 1 startDate, Nullable ' 1 endDate, Int32 effort, Nullable ' 1 active, Int32 currentPage, Int32 pageSize, Int32 sortId, Int32 sortName, Int32 sortTitle, Int32 sortTier, Int32 sortJoinedDate, Int32 sortDepartment) in d:'Projects'EzLife'_source' EzLife' app'EzLife. tasks 'EmployeeCudTasks.cs:line 206 '之前这是我的代码<>之前public static iquerable GetEmployeesQ(this iquerable employees, iquerable employeeTitles, int currentPage,int pageSize){Var query =查询员工中的员工在employeeTitles中加入employeeTitle在员工。Id等于employeeTitle.Employee.Idselect new EmployeeDto(){Id = employee。Id,CustomCode = employee。CustomCode,FirstName = employee。FirstName,LastName = employee。姓,midlename = employee。MiddleName,FullName =字符串。空的,JoinedDate =雇员。JoinedDate,};返回查询;}

public static IQueryable GetEmployeeTitlesQ(this IQueryable employeeTitles){从employeeTitles中的et1返回加入et2(从employeeTitles中获取orderby et.Employee。Id, et.StartDate将et. employee . id组到etmax中选择新的{Id = etmax。Max(et => et. id)}在……上;Id等于et2。Id选择et1;} '

我调用GetEmployeeTitlesQ在GetEmployeesQ为:'gettemployees (int currentPage = 1, int pageSize = 20){

IList<EmployeeDto> employees = new List<EmployeeDto>(); IQueryable<EmployeeTitle> employeeTitles = employeeTitleRep.GetAll().GetEmployeeTitlesQ(); IQueryable<EmployeeDto> employeeDto = employeeRep.GetAll().GetEmployeesQ( employeeTitles , jobTitles , currentPage , pageSize); try { employees = employeeDto.ToList(); } catch (Exception ex) { var mess = ex.Message.ToString(); } return employees; } 之前

'我猜Max()函数有问题,但我不知道为什么。有什么办法可以解决这个问题吗?

不支持NHibernate指定的方法

NHibernate不能将每个LINQ查询转换为SQL。对我来说,重新排列wherejoin的顺序就足够了。

我建议在你的代码中做以下修改,这帮助我克服了同样的异常:

public static IQueryable GetEmployeeTitlesQ(this IQueryable employeeTitles)
{
    var employeeTitlesEnumerable = employeeTitles.ToArray();
    return from et1 in employeeTitlesEnumerable 
           join et2 in (
               from et in employeeTitlesEnumerable 
               orderby et.Employee.Id, et.StartDate
               group et by et.Employee.Id into etmax
               select new { Id = etmax.Max(et => et.Id) }
           ) on et1.Id equals et2.Id
           select et1;
}

我在查询对象上添加了对.ToArray()的调用。我使用FluentNHibernate的经验是,有时返回的IQueryable试图将整个LINQ表达式转换为SQL。当查询涉及不能表示为SQL的对象时,将抛出您看到的错误。所以,我的猜测是,Max调用不被识别为NHibernate可以正确翻译的东西。

使用.ToArray()(或者如果你喜欢.ToList())将NHibernate的可查询对象转换为IEnumerable的实例,然后由。net框架完全处理。这意味着应用于IEnumerable的LINQ表达式将不再被转换为SQL。

上面的一个副作用是,您将无法对数据库执行整个select作为SQL查询。

底线(至少对我来说)是你应该在NHibernate层中仔细排序所有与数据库相关的操作,当查询完成时,将其转换为可枚举的,以防止潜在的进一步的LINQ操作从业务逻辑调用干扰IQueryable的内部细节。