拥有NHibernate实体:
Company
,Invoice
和InvoiceLine
,其小数属性为Price
。
Company
的集合类型为Invoice
,而Invoice
的集合类型为InvoiceLine
。
如何获取属于发票行的所有价格的总和,发票行属于由id指定的某个公司的发票?
我试着写这样的查询:
session
.Query<InvoiceLine>()
.Where(invoiceLine => invoiceLine.Invoice.Company.Id == companyId)
.Sum(invoiceLine => invoiceLine.Price);
但它引发了一个例外:
NHibernate.Exceptions.GenericADOException
"Could not execute query[SQL: SQL not available]"
at NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results)
at NHibernate.Impl.AbstractSessionImpl.List(IQueryExpression queryExpression, QueryParameters parameters)
at NHibernate.Impl.ExpressionQueryImpl.List()
at NHibernate.Linq.DefaultQueryProvider.ExecuteQuery(NhLinqExpression nhLinqExpression, IQuery query, NhLinqExpression nhQuery)
at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
at NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.Sum[TSource](IQueryable`1 source, Expression`1 selector)
内部异常:
System.ArgumentNullException
"Value cannot be null.\r\nParameter name: item"
at System.ThrowHelper.IfNullAndNullsAreIllegalThenThrow[T](Object value, ExceptionArgument argName)
at System.Collections.Generic.List`1.System.Collections.IList.Add(Object item)
at NHibernate.Util.ArrayHelper.<>c__DisplayClass2.<AddAll>b__0()
at NHibernate.Util.ArrayHelper.AddAll(IList to, IList from)
at NHibernate.Engine.Query.HQLQueryPlan.PerformList(QueryParameters queryParameters, ISessionImplementor session, IList results)
at NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results)
这可能与汇总空集合有关,但我不知道如何解决它。
答案 0 :(得分:9)
尝试将Price
强制转换为可为空的decimal
...
.Sum(invoiceLine => (decimal?)invoiceLine.Price) ?? 0;
结果显然是decimal?
答案 1 :(得分:0)
session
.Query<InvoiceLine>()
.Where(invoiceLine => invoiceLine.Invoice.Company.Id == companyId && invoiceLine.Price != null)
.Sum(invoiceLine => (decimal)invoiceLine.Price);
答案 2 :(得分:0)
标记为答案的解决方案并没有为我解决问题。我没有使用GenericAdoException,而是使用以下堆栈获得了InvalidOperationException。
此处提出的解决方案Linq: select property collection是我的实际解决方案。
Une erreur inattendue de type InvalidOperationException s'est produite sur le serveur
System.InvalidOperationException: Code supposed to be unreachable
à System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
à System.Linq.Expressions.Compiler.StackSpiller.RewriteUnaryExpression(Expression expr, Stack stack)
à System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
à System.Linq.Expressions.Compiler.StackSpiller.RewriteExpressionFreeTemps(Expression expression, Stack stack)
à System.Linq.Expressions.Compiler.StackSpiller.Rewrite[T](Expression`1 lambda)
à System.Linq.Expressions.Expression`1.Accept(StackSpiller spiller)
à System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression lambda, DebugInfoGenerator debugInfoGenerator)
à System.Linq.Expressions.Expression`1.Compile()
à NHibernate.Linq.ExpressionToHqlTranslationResults.MergeLambdasAndCompile[TDelegate](IList`1 itemTransformers)
à NHibernate.Linq.ExpressionToHqlTranslationResults..ctor(HqlTreeNode statement, IList`1 itemTransformers, IList`1 listTransformers, IList`1 postExecuteTransformers, List`1 additionalCriteria)
à NHibernate.Linq.IntermediateHqlTree.GetTranslation()
à NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery(QueryModel queryModel, VisitorParameters parameters, Boolean root)
à NHibernate.Linq.NhLinqExpression.Translate(ISessionFactoryImplementor sessionFactory, Boolean filter)
à NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)
à NHibernate.Engine.Query.QueryExpressionPlan.CreateTranslators(IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
à NHibernate.Engine.Query.QueryExpressionPlan..ctor(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
à NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`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.Execute(Expression expression)
à NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)
à System.Linq.Queryable.Sum[TSource](IQueryable`1 source, Expression`1 selector)
à Secib.Server.Services.ReglementService.GetRegleTtc(FactureView facture) dans x:\Sources\Next\Alpha\SecibNext\Secib.Server\Services\ReglementService.cs:ligne 425
à Secib.Server.Services.ReglementService.DoesMontantSoldeFacture(FactureView facture, Decimal montantImpute) dans x:\Sources\Next\Alpha\SecibNext\Secib.Server\Services\ReglementService.cs:ligne 391
à Secib.Server.Services.ReglementService.DispatcheMontantImpute(Reglement reglement, ReglementFactureCompactDto factureDto) dans x:\Sources\Next\Alpha\SecibNext\Secib.Server\Services\ReglementService.cs:ligne 236
à Secib.Server.Services.ReglementService.SaveReglement(Reglement reglement, IList`1 factures) dans x:\Sources\Next\Alpha\SecibNext\Secib.Server\Services\ReglementService.cs:ligne 197
à Secib.Server.Controllers.ReglementController.<SaveReglement>z__OriginalMethod() dans x:\Sources\Next\Alpha\SecibNext\Secib.Server\Controllers\ReglementController.cs:ligne 141
à Secib.Server.Controllers.ReglementController.<SaveReglement>c__Binding.Invoke(Object& instance, Arguments arguments, Object aspectArgs) dans :ligne 0
à PostSharp.Aspects.Internals.MethodInterceptionArgsImpl`1.Proceed()
à Secib.Server.Aspects.TransactionAspect.OnInvoke(MethodInterceptionArgs args) dans x:\Sources\Next\Alpha\SecibNext\Secib.Server\Aspects\TransactionAspect.cs:ligne 32