[英]NHibernate Specified method is not supported
我使用S#arpLite開發了webapp來構建查詢以從許多表中獲取列表。 使用NHibernate版本3.3.1.4000
我在運行時收到來自應用的錯誤消息,例如
`NHibernate System.NotSupportedException Specified method is not supported. {Name = "PolymorphicQuerySourceDetector" FullName = "NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector"} at NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector.GetClassName(IASTNode querySource) at NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector.Process(IASTNode tree) at NHibernate.Hql.Ast.ANTLR.AstPolymorphicProcessor.Process() at NHibernate.Hql.Ast.ANTLR.AstPolymorphicProcessor.Process(IASTNode ast, ISessionFactoryImplementor factory) at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IASTNode ast, String queryIdentifier, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory) 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.Collections.Generic.List`1..ctor(IEnumerable`1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) at EzLife.Tasks.EmployeeCudTasks.GetEmployees(List`1 listSkill, List`1 listDepartment, List`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 IQueryable GetEmployeesQ(this IQueryable employees, IQueryable employeeTitles, int currentPage,int pageSize) { var query = from employee in employees join employeeTitle in employeeTitles on employee.Id equals employeeTitle.Employee.Id select new EmployeeDto() { Id = employee.Id, CustomCode = employee.CustomCode, FirstName = employee.FirstName, LastName = employee.LastName, MiddleName = employee.MiddleName, FullName = string.Empty, JoinedDate = employee.JoinedDate, }; return query; }public static IQueryable GetEmployeeTitlesQ(this IQueryable employeeTitles) { return from et1 in employeeTitles join et2 in ( from et in employeeTitles 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; }`
I call GetEmployeeTitlesQ in GetEmployeesQ as : ' public IList GetEmployees(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無法將每個LINQ查詢轉換為SQL。 對我來說,只需重新排列where
和join
語句的順序就足夠了。
我建議您對代碼進行以下更改,這有助於我克服同樣的異常:
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。
上面的副作用是,您將無法對數據庫執行整個選擇作為SQL查詢。
最重要的是(至少對我來說),您應該仔細地對NHibernate層中所有與數據庫相關的操作進行排序,並且在完成查詢后,將其轉換為可枚舉,以防止業務邏輯調用潛在的進一步LINQ操作干擾該操作。 IQueryable
的內部細節。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.