NHibernate Linq无法调用返回IQueryable <t> </t>的常规方法

时间:2011-08-09 14:19:50

标签: .net nhibernate linq-to-nhibernate

我有以下查询:

public ICollection<AccountAbsence> GetAccountAbsencesByRosters(WorkRoster[] workRosters)
{
    var processedWorkRosters = from workRoster in workRosters
                               select new WorkRoster
                               {
                                   Start = DateUtil.SyncToCrmTime(workRoster.Start),
                                   End = DateUtil.SyncToCrmTime(workRoster.End),
                                   ServicePlan = workRoster.ServicePlan
                               };

    return (from absence in GetNonCanceledAbsencesCriteria()
            where processedWorkRosters.Any(workRoster => workRoster.ServicePlan.Account.Id == absence.Account.Id && ((absence.End.HasValue && absence.End > workRoster.Start && absence.Start < workRoster.End) || (!absence.End.HasValue && absence.Start <= workRoster.End)))
            select absence).ToList();

}

    private IQueryable<AccountAbsence> GetNonCanceledAbsencesCriteria()
    {
        return ActiveRecordLinq.AsQueryable<AccountAbsence>().AsQueryable()
                                    .Where(absence => absence.CancelDate == null || absence.CancelReason == null);
    }

由于某种原因,无法评估GetNonCanceledAbsencesCriteria() 这是我得到的例外:

Message: Specified method is not supported.
Stack Trace:    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.NhQueryProvider.PrepareQuery(Expression expression
IQuery& query
NhLinqExpression& nhQuery)
   at NHibernate.Linq.NhQueryProvider.Execute(Expression expression)
   at NHibernate.Linq.NhQueryProvider.Execute[TResult](Expression expression)
   at Remotion.Data.Linq.QueryableBase`1.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Danel.Nursing.Scheduling.Actions.DataServices.AccountAbsenceDataService.GetAccountAbsencesByRosters(WorkRoster[] workRosters) in D:\Work\DanelNursing\branches\AugustVersion\Scheduling\Danel.Nursing.Scheduling.Actions\DataServices\AccountAbsenceDataService.cs:line 102
   at Danel.Nursing.Scheduling.Actions.Validators.AccountAbsenceWorkRostersValidator.GetFailedWorkRosters() in D:\Work\DanelNursing\branches\AugustVersion\Scheduling\Danel.Nursing.Scheduling.Actions\Validators\AccountAbsenceWorkRostersValidator.cs:line 50
   at Danel.Nursing.Scheduling.Actions.Generators.WorkingJournalsDataGenerator.generateLists(Branch branch
Int32 month
Int32 year) in D:\Work\DanelNursing\branches\AugustVersion\Scheduling\Danel.Nursing.Scheduling.Actions\Generators\WorkingJournalsDataGenerator.cs:line 412
   at Danel.Nursing.Scheduling.Actions.Generators.WorkingJournalsDataGenerator.Generate(Branch branch
Int32 month
Int32 year) in D:\Work\DanelNursing\branches\AugustVersion\Scheduling\Danel.Nursing.Scheduling.Actions\Generators\WorkingJournalsDataGenerator.cs:line 108
   at Danel.Nursing.Scheduling.Controllers.WorkingJournalsController.<>c__DisplayClass37.<ShowWorkingJournalsData>b__32() in D:\Work\DanelNursing\branches\AugustVersion\Scheduling\Danel.Nursing.Scheduling\Controllers\WorkingJournalsController.cs:line 826
   at Danel.Nursing.Scheduling.Viewlets.WaitForAction.Worker_DoWork(Object sender
DoWorkEventArgs e) in D:\Work\DanelNursing\branches\AugustVersion\Scheduling\Danel.Nursing.Scheduling\Viewlets\WaitForAction.cs:line 40

似乎LINQ提供商应该能够解决这个问题 我在这里遗漏了什么或者没有实施? 编辑:
看来我错了,并且无法评估processedWorkRosters.Any() 我应该如何与外部阵列进行比较呢?

1 个答案:

答案 0 :(得分:3)

方法GetNonCanceledAbsencesCriteria()返回一个IQueryable,它与NH提供者一致,这意味着你对它执行的任何操作都很可能被解释为SQL语言。

from absence in GetNonCanceledAbsencesCriteria()
where processedWorkRosters.Any( ... )
select absence

上面的问题是processedWorkRosters是NH Linq提供者的外来变量,这意味着它不知道如何将它们翻译成sql speak。

尝试:

from absence in GetNonCanceledAbsencesCriteria().ToArray()
where processedWorkRosters.Any( ... )
select absence

ToArray()强制立即评估GetNonCanceledAbsencesCriteria(),但可能不是最佳(或不是)......如果是,您可能需要将where子句重写为“close-to “SQL说。