2016-02-17 4 views
0

Я пытаюсь оптимизировать два запроса к БД в один, как это:NHibernate производит System.ArgumentException

var subQuery = Session 
     .Query<IProfile>() 
     .Where(profile => accountIds.Contains(profile.AccountId)) 
     .GroupBy(profile => profile.AccountId) 
     .Select(kv => kv.Max(profile => profile.Id)); 
     //.ToList(); 

    var outQuery = Session 
     .Query<IProfile>() 
     .Where(profile => subQuery.Contains(profile.Id)) 
     .Fetch(profile => profile.User) 
     .Fetch(profile => profile.Email); 

    var result = outQuery.ToList(); 

но Продусе в System.ArgumentException

но если это два отдельных запросов к БД например

var subQuery = Session 
     .Query<IProfile>() 
     .Where(profile => accountIds.Contains(profile.AccountId)) 
     .GroupBy(profile => profile.AccountId) 
     .Select(kv => kv.Max(profile => profile.Id)) 
     .ToList(); 

все работает нормально.

Более подробная информация об исключении:

'System.Nullable1 [System.Int64]' не может быть использован в качестве типа данных для последовательности с ItemExpression типа «System.Nullable1 [System.Int64 ]». Имя параметра: DATATYPE

в Remotion.Linq.Clauses.StreamedData.StreamedSequenceInfo.AdjustDataType (тип DATATYPE) в Remotion.Linq.QueryModel.GetOutputDataInfo() в Remotion.Linq.QueryModel.GetResultType() в NHibernate .Linq.NestedSelects.NestedSelectRewriter.ProcessSubquery (ISessionFactory SessionFactory, ICollection1 elementExpression, queryModel queryModel, выражение группы, queryModel subQueryModel) при NHibernate.Linq.NestedSelects.NestedSelectRewriter.ProcessExpression (queryModel queryModel, ISessionFactory SessionFactory, выражение выражение, List1 elementExpression, Paramete группа rExpression) при NHibernate.Linq.NestedSelects.NestedSelectRewriter.ReWrite (QueryModel queryModel, ISessionFactory SessionFactory) в NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery (QueryModel queryModel, параметры VisitorParameters, булева корень) в NHibernate.Linq. Visitors.HqlGeneratorExpressionTreeVisitor.VisitSubQueryExpression (SubQueryExpression выражение) на NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitExpression (Expression выражение) при NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.Visit (выражение выражения, параметры VisitorParameters) при NHibernate.Linq .Visitors.QueryModelVisit or.VisitWhereClause (WhereClause WhereClause, QueryModel queryModel, индекс Int32) при Remotion.Linq.Clauses.WhereClause.Accept (IQueryModelVisitor посетитель, QueryModel queryModel, индекс Int32) при Remotion.Linq.QueryModelVisitorBase.VisitBodyClauses (ObservableCollection1 bodyClauses, queryModel queryModel) при Remotion.Linq.QueryModelVisitorBase.VisitQueryModel (queryModel queryModel) при NHibernate.Linq.Visitors.QueryModelVisitor.Visit()
на NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery (queryModel queryModel, параметры VisitorParameters, Boolean root) в NHibernate.Linq.NhLinqExpression.Translate (ISession FactoryImplementor SessionFactory, Boolean фильтр) в NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators (IQueryExpression QueryExpression, String collectionRole, Boolean неглубоко, IDictionary2 фильтры, ISessionFactoryImplementor завод) в NHibernate.Engine.Query.QueryExpressionPlan.CreateTranslators (IQueryExpression QueryExpression, String collectionRole, Boolean неглубоко, IDictionary2 enabledFilters, ISessionFactoryImplementor завод) в NHibernate.Engine.Query.QueryExpressionPlan..ctor (IQueryExpression QueryExpression, булевой отмели, IDictionary2 enabledFilters, ISessionFactoryImplementor завод) в NHibernate. Engine.Query.QueryPlanCache.GetHQLQueryPlan (IQueryExpression QueryExpression, булева неглубоко, IDictionary2 enabledFilters) при NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan (IQueryExpression QueryExpression, булева неглубокой) при NHibernate.Impl.AbstractSessionImpl.CreateQuery (IQueryExpression queryExpre ssion) при NHibernate.Linq.DefaultQueryProvider.PrepareQuery (Expression выражение, IQuery & запроса, NhLinqExpression & nhQuery) при NHibernate.Linq.DefaultQueryProvider.Execute (выражение Выражение)
в NHibernate.Linq.DefaultQueryProvider.Execute [TResult] (выражение выражение) в Remotion.Linq.QueryableBase1.GetEnumerator() в System.Collections.Generic.List1..ctor (сбор IEnumerable1) при System.Linq.Enumerable.ToList [TSource] (источник IEnumerable1)

ответ

0

Можете ли вы попытаться переписать два запроса в сочетании вот так:

Session.Query<IProfile>() 
    .Where(profile => 
     Session.Query<IProfile>() 
      .Where(pf => accountIds.Contains(pf.AccountId)) 
      .GroupBy(pf => pf.AccountId) 
      .Select(kv => kv.Max(pf => pf.Id)) // subQuery 
      .Any(id => profile.Id == id)) // outQuery 
    .Fetch(profile => profile.User) 
    .Fetch(profile => profile.Email); 
+0

Я могу, но поймал ту же ошибку :( –

+0

hm, я понимаю. Я полагаю, что «AccountId» или «Id профиля» имеют значение NULL, попробуйте аналогичный подход, например здесь http://stackoverflow.com/questions/2023010/nhibernate-linq-system-nullable-throws-argumentexception-the-value-is-not -ты – mariovalens

+0

я думал об этом раньше и судимых сделать так: вар подзапроса = Session .Query () .гд (профиль => accountIds.Contains (profile.AccountId)) .GroupBy (профиль => профиль .AccountId) . Выберите (kv => kv.Max (профиль => profile.Id.Value)); вар outQuery = Session .Query () .гд (профиль => subQuery.Contains (profile.Id.Value)) ... ошибки была что-то вроде (то же самое, но без обнуляемых): «[System. Int64] 'не может использоваться в качестве типа данных для последовательности с ItemExpression типа' [System.Int64] '. И AccountId не может быть недействительным –