2011-08-09 48 views
2

我有以下查詢一個普通的方法:NHibernate的LINQ的不能調用返回一個IQueryable <T>

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()不能被評估。
我應該如何與外部數組比較?

+0

您可以請嘗試將GetNonCanceledAbsencesCriteria()存儲到局部變量,然後在您的LINQ查詢中使用該變量。 –

+0

@degorolls試過了。相同的結果。還有其他建議嗎? –

回答

3

方法GetNonCanceledAbsencesCriteria()返回一個IQueryable,它來自NH提供者,這意味着您對它執行的任何操作都非常有可能被解釋爲SQL說話。

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

的問題與上面是processedWorkRosters是一個變量國外的NH LINQ提供程序,這意味着它不知道如何將其轉化爲SQL說話。

嘗試:

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

ToArray()強制立即評估GetNonCanceledAbsencesCriteria(),但可能不是最優的(或沒有)......如果是你可能需要重新寫在where子句「關閉到「SQL說話。

+0

在這種情況下,這是非常不理想的。 –

+0

我接受這個,因爲這是正確的答案,雖然我不滿意它。 –

相關問題