2013-08-08 37 views
6

Có tổ chức NHibernate:LINQ to NHibernate: tổng số tiền

Company, InvoiceInvoiceLine trong đó có một tài sản Price thập phân.

A Company có bộ sưu tập loại InvoiceInvoice có bộ sưu tập loại InvoiceLine.

Làm cách nào để có được tổng của tất cả các giá thuộc về các dòng hóa đơn thuộc về hóa đơn của một công ty cụ thể được chỉ định bởi id?

Tôi cố gắng để viết các truy vấn như thế này:

session 
    .Query<InvoiceLine>() 
    .Where(invoiceLine => invoiceLine.Invoice.Company.Id == companyId) 
    .Sum(invoiceLine => invoiceLine.Price); 

nhưng nó ném một ngoại lệ:

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) 

ngoại lệ bên trong:

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) 

Điều này có thể có cái gì để làm với tổng hợp các bộ sưu tập trống nhưng tôi không chắc chắn cách khắc phục nó.

Trả lời

7

Hãy thử đúc các Price để nullable decimal ...

.Sum(invoiceLine => (decimal?)invoiceLine.Price) ?? 0; 

Kết quả rõ ràng là một decimal?

+0

Đây gần như là giải pháp, vui lòng thay đổi thành '.Sum (invoiceLine => (decimal?) InvoiceLine.Price) ?? 0' vì vậy tôi có thể upvote và chấp nhận. –

0
session 
    .Query<InvoiceLine>() 
    .Where(invoiceLine => invoiceLine.Invoice.Company.Id == companyId && invoiceLine.Price != null) 
    .Sum(invoiceLine => (decimal)invoiceLine.Price); 
0

Giải pháp đánh dấu là câu trả lời không lưu các vấn đề đối với tôi. Thay vì GenericAdoException tôi nhận được một InvalidOperationException với ngăn xếp sau đây.

Giải pháp đề xuất ở đây Linq: select property collection là giải pháp thực tế đối với tôi.

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 
+0

Ngoại lệ bên trong nơi bạn nhận được và truy vấn/thực thể của bạn trông như thế nào? Trừ khi một cái gì đó thay đổi theo cách nó hoạt động, tôi khá chắc chắn câu trả lời được chấp nhận hoạt động. –

+0

Đoạn mã thứ hai 'SelectMany' cũng làm 2 yêu cầu cho DB thay vì 1 (có thể được viết bằng cách sử dụng tương lai nhưng nó vẫn sẽ kém hiệu quả hơn). –

+0

InnerException là null. Truy vấn là rất đơn giản và rất giống như của bạn: trở Session.Query () \t \t \t \t .Where (x => x.Facture == facture) \t \t \t \t .Sum (x => (decimal?) x.MontantRegle ?? 0); Trong đó Facture được tham chiếu bởi ReglementFacture (nhiều đến một) và MontantRegle là số thập phân (và cột không thể rỗng). NH v 4.0.0.4000 –