NHibernate group by and order by division of two conditional sum - nhibernate

I have the following code:
var classAttendanceDetails =
Session.QueryOver<StudentClassAttendanceDetails>(() => scadAlias)
.JoinAlias(() => scadAlias.StudentClassAttendence, () => scaAlias)
.JoinAlias(() => scaAlias.Lecture, () => lAlias).JoinAlias(() => scaAlias.Teacher, () => tAlias).JoinAlias(() => scadAlias.StudentProgram, () => spAlias);
var queryover = classAttendanceDetails
.Select(
Projections.Group<StudentClassAttendanceDetails>(c => scaAlias.Lecture),
Projections.Group<StudentClassAttendanceDetails>(c => scaAlias.Teacher),
Projections.Sum(
Projections.Conditional(
Restrictions.Where<StudentClassAttendanceDetails>(f => f.StudentFeedback == 1),
Projections.Constant(1),
Projections.Constant(0))),
Projections.Sum(
Projections.Conditional(
Restrictions.Where<StudentClassAttendanceDetails>(f => f.StudentFeedback == 2),
Projections.Constant(1),
Projections.Constant(0))),
Projections.Sum(
Projections.Conditional(
Restrictions.Where<StudentClassAttendanceDetails>(f => f.StudentFeedback == 3),
Projections.Constant(1),
Projections.Constant(0))),
Projections.Sum(
Projections.Conditional(
Restrictions.Where<StudentClassAttendanceDetails>(
f => f.StudentFeedback.IsIn(new[] {1, 2, 3})),
Projections.Constant(1),
Projections.Constant(0))),
Projections.SqlFunction(
new VarArgsSQLFunction("(", "/", ")"),
NHibernateUtil.Int32,
Projections.Sum(
Projections.Conditional(
Restrictions.Where<StudentClassAttendanceDetails>(f => f.StudentFeedback == 1),
Projections.Constant(1),
Projections.Constant(0))),
Projections.Conditional(
Restrictions.Where<StudentClassAttendanceDetails>(f => f.StudentFeedback.IsIn(new[] { 1, 2, 3 })),
Projections.Constant(1),
Projections.Constant(0)))
).OrderBy(Projections.SqlFunction(
new VarArgsSQLFunction("(", "/", ")"),
NHibernateUtil.Int32,
Projections.Sum(
Projections.Conditional(
Restrictions.Where<StudentClassAttendanceDetails>(f => f.StudentFeedback == 1),
Projections.Constant(1),
Projections.Constant(0))),
Projections.Conditional(
Restrictions.Where<StudentClassAttendanceDetails>(f => f.StudentFeedback.IsIn(new[] { 1, 2, 3 })),
Projections.Constant(1),
Projections.Constant(0)))).Desc;
Here I am trying to order the result by number of results where feedback is 1 devided by no of results where feedback is 1/2/3.But i can not order by this because it is not included in the group by.How can i include it in group by

Related

SQL query takes too long to execute. Need to improve performance of query

I'm using SQL Server, .NET 5 environment. This SQL query takes too long to execute. This query waiting time is almost 3 min but there are only 35 records. Are there better way to optimize this query ?
var allmeetings = await _context.MeetingMaster
.Where(x => x.IsActive == true &&
(x.MeetingParticipants.Any(y => y.ParticipantId == Convert.ToInt32(_currentUserService.CurrentUserId)) ||
x.OrganizedById == Convert.ToInt32(_currentUserService.CurrentUserId)))
.Include(a => a.MeetingParticipants)
.ThenInclude(b => b.Participant)
.Include(a => a.MeetingAgendaItems)
.ThenInclude(e => e.MeetingActionItems)
.ThenInclude(w => w.ActionItemLogs)
.Include(a => a.MeetingAgendaItems)
.ThenInclude(e => e.MeetingActionItems)
.ThenInclude(w => w.ActionItemResposibilities)
.Include(g => g.MeetingAgendaItems)
.ThenInclude(v => v.MeetingAgendaItemTypes)
.ThenInclude(j => j.AgendaItemRef)
.Include(w => w.MeetingAgendaItems)
.ThenInclude(d => d.RestrictedAgendaItemList)
.ThenInclude(s => s.ParticipantRef)
.Include(s => s.MeetingAgendaItems)
.ThenInclude(q => q.MeetingAgendaItemSupportiveDocuments)
.Include(c => c.MonthsRef)
.Include(z => z.YearsRef)
.Include(g => g.MeetingMinutesDoc)
.Include(c => c.Project)
.Include(c => c.Category)
.Include(l => l.MeetingSuggestions)
.Include(q => q.MeetingMattersArises)
.ThenInclude(i => i.MattersAriseResponsibilities)
.ThenInclude(s => s.ResponsiblePerson)
.Include(e => e.MeetingMattersArises)
.ThenInclude(w => w.MattersAriseReviewerComments)
.Include(s => s.MeetingMattersArises)
.ThenInclude(e => e.MattersAriseLogs)
.AsSplitQuery()
.ToListAsync(cancellationToken);
var result = allmeetings.Where(x => x.IsActive == true &&
x.isRecurringMeeting == false &&
(x.MeetingParticipants.Any(y => y.ParticipantId == Convert.ToInt32(_currentUserService.CurrentUserId)) || x.OrganizedById == Convert.ToInt32(_currentUserService.CurrentUserId))).ToList();
var RecMeetings = allmeetings.Where(x => x.IsActive == true &&
x.isRecurringMeeting == true &&
(x.MeetingParticipants.Any(y => y.ParticipantId == Convert.ToInt32(_currentUserService.CurrentUserId)) || x.OrganizedById == Convert.ToInt32(_currentUserService.CurrentUserId))).ToList();
var groupedRecMeetings = RecMeetings.GroupBy(u => u.MeetingRefId.Substring(0, u.MeetingRefId.LastIndexOf('-'))).Select(grp => grp.ToList()).ToList();
var GraeterMeetings = new List<MeetingMaster>();
foreach (var met in groupedRecMeetings)
{
result.AddRange(met.FindAll(x => x.MeetingStatus != "Initiated" ));
GraeterMeetings.AddRange(met.FindAll(x => x.MeetingStatus == "Initiated"));
if(GraeterMeetings.Count != 0)
{
result.Add(GraeterMeetings.OrderBy(x => x.MeetingDate).First());
}
GraeterMeetings.Clear();
}
return result.OrderByDescending(d => d.Id).ToList();
First of all you have so many Includes() and ThenIncludes(), this if really bad for your performance. Is there a way by any chance you can reduce these includes -> only use the necessary one's.
Then i would that you execute the .ToList() query at the end of the statement (befor your return)
Down below is an example how i've done it in the past (with pagination & filtration):
var context = _context.People
.Include(x => x.Parents)
.ThenInclude(x => x.Adress)
.Include(x => x.Job)
.Include(x => x.Hobbies);
var items = string.IsNullOrWhiteSpace(query)
? context
: context.Where(x => x.Name.Contains(query));
var filters = new List<int>();
if (filter != null)
{
filters = filter.Split(',').Select(int.Parse).ToList();
items = items.Where(x => x.Parents.Select(s => s.AdressId).Any(z => filters.Any(y => y == z)));
}
return await items.Skip(page * take).Take(take).ToListAsync();

Show a pdf on CakePhp after creating and seving it

it's my first post so sorry in case i will do some mistakes. I am getting mad from this morning because of this function:
public function viewpdf0($agent_id = null, $month = null, $year = null){
if(!empty($agent_id)){
$this->create_remittance($agent_id, $month, $year);
$this->layout = '/pdf/default';
$this->render('/Pdf/remittance_0');
sleep(1);
$this->redirect('/files/remittances/STAT_'.str_pad($month, 2, '0', STR_PAD_LEFT).'_'.str_pad($year, 0, '0', STR_PAD_LEFT).'_'.$agent['Registry']['hash'].'_TEMP.pdf');
}
}
The problem started when i decided to take off the calculations from the viewpdf0 function and putting it into the create_remittance function.
When i click on the button "Print Pdf" i get the following error:
Missind Controller for files. This mean that the Cakephp is processing the redirect thinking to find a controller called files!!!!
It's very strange, because if i put again the calculation functions directly inside the viewpdf0 function it works.
Below part of the create_remittance function:
public function create_remittance($agent_id = null, $month = null, $year = null) {
$agent = $this->Registry->findById($agent_id);
$this->set('agent', $agent);
$conditions = array();
array_push($conditions , array('Dossier.active' => '1'));
array_push($conditions , array('Edossier.active' => '1'));
array_push($conditions , array('OR' =>
array(
array(
'Dossier.item_parent_id' => '43'
),
array(
'Dossier.item_parent_id' => '44'
)
)
));
//20:POLIZZA EMESSA - 17:PERFEZIONATA - 14:ATTESA DOC. ORIGINALI - 18:CARICATA
array_push($conditions , array('Dossier.state_id' => array(20,17,14,18)));
array_push($conditions , array('EXTRACT(MONTH FROM "Edossier"."date_emissione") =' => $month));
array_push($conditions , array('EXTRACT(YEAR FROM "Edossier"."date_emissione") =' => $year));
array_push($conditions , array('Dossier.agent_id' => $agent_id));
$query = array(
'fields' => array( 'DISTINCT Dossier.id',
'Agent.surname'
),
'joins' => array(
array('table' => 'items',
'alias' => 'Item',
'type' => 'LEFT',
'conditions' => array('Dossier.item_id = Item.id'),
),
array('table' => 'edossiers',
'alias' => 'Edossier',
'type' => 'LEFT',
'conditions' => array('Edossier.dossier_id = Dossier.id'),
),
array('table' => 'registries',
'alias' => 'Registry',
'type' => 'LEFT',
'conditions' => array('Dossier.registry_id = Registry.id'),
),
array('table' => 'registries',
'alias' => 'Agency',
'type' => 'LEFT',
'conditions' => array('Dossier.insurance_agency_id = Agency.id'),
),
array('table' => 'registries',
'alias' => 'Company',
'type' => 'LEFT',
'conditions' => array('Dossier.insurance_company_id = Company.id'),
),
array('table' => 'states',
'alias' => 'State',
'type' => 'LEFT',
'conditions' => array('Dossier.state_id = State.id'),
),
array('table' => 'categories',
'alias' => 'Product',
'type' => 'LEFT',
'conditions' => array('Dossier.item_parent_id = Product.id'),
),
array('table' => 'registries',
'alias' => 'Agent',
'type' => 'LEFT',
'conditions' => array('Dossier.agent_id = Agent.id'),
),
array('table' => 'states',
'alias' => 'RenewedState',
'type' => 'LEFT',
'conditions' => array('Dossier.renewed_state_id = RenewedState.id'),
),
),
'conditions' => $conditions,
'recursive' => -1
);
$dossiers = $this->Dossier->find('all', $query);
$this->set('dossiers', $dossiers);
$debug_dossier = '';
$edossiers = array();
$edossiers3 = array();
$dossier_ids = array();
$total_gross = 0;
$total_taxes = 0;
$total_equity = 0;
$total_fees_gross = 0;
$total_bill_tax = 0;
foreach($dossiers as $dossier){
// Query su type=1 ossia rata di pagamento
$edossier_all = $this->Edossier->find('all', array(
'conditions' => array(
'Edossier.active' => '1',
'Edossier.dossier_id' => $dossier['Dossier']['id'],
'Edossier.type' => '1',
'Edossier.month' => $month,
'Edossier.year' => $year
),
'order' => array(
'Edossier.id ASC'
)
));
// Query su type=2 ossia storno di pagamento
$edossier3_all = $this->Edossier->find('all', array(
'conditions' => array(
'Edossier.active' => '1',
'Edossier.dossier_id' => $dossier['Dossier']['id'],
'Edossier.type' => '2',
'Edossier.month' => $month,
'Edossier.year' => $year
),
'order' => array(
'Edossier.id ASC'
)
));
foreach($edossier_all as $edossier){
if(!empty($edossier)){
$item = $this->Item->findById($edossier['Dossier']['item_id']);
$agent_name = $this->Registry->findById($edossier['Dossier']['agent_id']);
$state = $this->State->findById($edossier['Dossier']['state_id']);
$registry = $this->Registry->findById($edossier['Dossier']['registry_id']);
$cashflow = $this->Cashflow->findByHash($edossier['Edossier']['cashflow_hash']);
$edossier['Agent'] = $agent_name;
$edossier['Item'] = $item;
$edossier['State'] = $state;
$edossier['Registry'] = $registry;
$edossier['Cashflow'] = $cashflow;
array_push($edossiers, $edossier);
$total_gross = $total_gross + $edossier['Edossier']['gross'];
$total_taxes = $total_taxes + $edossier['Edossier']['taxes'];
$total_equity = $total_equity + $edossier['Edossier']['equity'];
$total_fees_gross = $total_fees_gross + $edossier['Edossier']['fees_gross'];
$total_bill_tax = $total_bill_tax + $edossier['Edossier']['bill_tax'];
}
}
foreach($edossier3_all as $edossier3){
if(!empty($edossier3)){
$total_gross = $total_gross - $edossier3['Edossier']['value'];
$total_taxes = $total_taxes - $edossier3['Edossier']['taxes'];
$total_equity = $total_equity - $edossier3['Edossier']['equity'];
$total_fees_gross = $total_fees_gross - $edossier3['Edossier']['fees_gross'];
$total_bill_tax = $total_bill_tax - $edossier3['Edossier']['bill_tax'];
array_push($edossiers3, $edossier3);
}
}
array_push($dossier_ids, $dossier['Dossier']['id']);
$debug_dossier .= $dossier['Dossier']['id'] .',';
}
//Trovo tutte le rate pagate per conteggiare il totale pagato, nelle successive righe
$edossiers2 = $this->Edossier->find('all', array(
'conditions' => array(
'Edossier.active' => '1',
'Edossier.dossier_id' => $dossier_ids,
'Edossier.payed' => '1',
'Edossier.month' => $month,
'Edossier.year' => $year
)
));
$edossier_ids = array();
foreach($edossiers as $edossier){
array_push($edossier_ids, $edossier['Edossier']['id']);
}
$total_payed = 0;
foreach($edossiers2 as $edossier2){
//$cashflow = $this->Cashflow->findByHash($edossier2['Edossier']['cashflow_hash']);
//$total_payed = $total_payed + $cashflow['Cashflow']['qty'];
$cashflows = $this->Cashflow->find('all', array(
'conditions' => array(
'Cashflow.edossier_id' => $edossier2['Edossier']['id'],
'Cashflow.active' => '1'
)
));
foreach ($cashflows as $cashflow) {
$total_payed = $total_payed + $cashflow['Cashflow']['qty'];
}
}
$this->set('total_gross', $total_gross);
$this->set('total_taxes', $total_taxes);
$this->set('total_equity', $total_equity);
$this->set('total_fees_gross', $total_fees_gross);
$this->set('total_bill_tax', $total_bill_tax);
$this->set('total_payed', $total_payed);
$this->set('edossiers3', $edossiers3);
$this->set('edossiers2', $edossiers2);
$this->set('edossiers', $edossiers);
$this->set('agent', $agent);
$this->set('dossier_ids', $dossier_ids);
$this->set('edossier_ids', $edossier_ids);
$this->set('month', $month);
$this->set('year', $year);
$this->set('debug_dossier', $debug_dossier);
}
I solved the issue just inserting an array return in the function create_remittance and in the function viewpdf0 i fixed in this way:
$remittance = $this->create_remittance($agent_id, $month, $year);
Thank you.

How to create refund and register payment XML-RPC odoo

How can i create a refund and register payment for that refund in odoo via xml-rpc. The code that i have so far it creates the invoice for refund but it doesn't register any payment for that invoice, so the costumer refund invoice stays in open state even though a voucher is created and posted.
$invoiceData = $OERP->searchread(array(array('id','=',$invoiceId )), 'account.invoice');
$invoiceDatas = array();
foreach($invoiceData as $data)
{
$invoiceDatas["amount_total"] = $data["amount_total"];
$invoiceDatas["partner_id"] = $data["partner_id"];
$invoiceDatas["account_id"] = $data["account_id"];
$invoiceDatas["invoice_line"] = $data["invoice_line"];
$invoiceDatas["reference"] = $data["reference"];
$invoiceDatas["period_id"] = $data["period_id"];
}
$invoiceLineData = $OERP->searchread(array(array('invoice_id','=', intval($invoiceId) )), 'account.invoice.line');
foreach($invoiceLineData as $data)
{
$invoiceLine["product_id"] = $data["product_id"];
$invoiceLine["price_unit"] = $data["price_unit"];
}
$createRefundParams = array(
'date_invoice' => date('Y/m/d'),
'partner_id' => $invoiceDatas["partner_id"][0],
'journal_id' => 3,// $journalId,
'account_id' => $invoiceDatas["account_id"][0],
'name'=>'front end refundi',
'type'=>'out_refund' // dallon invoicen nga refund
);
$createRefund = $OERP->create($createRefundParams, 'account.invoice');
$invoiceProduct = array(
'invoice_id'=>$createRefund,
'product_id'=>$invoiceLine["product_id"][0],
'name'=>'refund',
'price_unit'=>$invoiceLine["price_unit"],
);
$createRefundLines = $OERP->create($invoiceProduct,"account.invoice.line");
$validateRefund = $OERP->workflow('account.invoice', 'invoice_open', $createRefund);
$amount_total = -$invoiceDatas['amount_total'];
$newInvoice = $OERP -> searchread(array(array('id','=',$createRefund)),'account.invoice' );
$moveId = array();
foreach($newInvoice as $data)
{
$moveId["move_id"] = $data["move_id"];
}
$createVoucher = array(
'date' => date('Y/m/d'),
'partner_id' => $invoiceDatas['partner_id'][0],
'amount' =>$amount_total ,
'journal_id' => 7,// $journalId,
'account_id' => 25,
'period_id' => $invoiceDatas['period_id'][0],
'type' => 'receipt'
);
$voucherResult = $OERP->create($createVoucher, 'account.voucher');
$invoice_object_line = $OERP->searchread(array(array('move_id', '=', $moveId["move_id"][0])), 'account.move.line');
$voucherLineItems = array(
'journal_id' => 7,// $journalId,
'period_id' => $invoiceDatas['period_id'][0],
'date' => date('Y/m/d'),
'date_due' => date('Y/m/d'),
'name' => 'Payment for refund',
'payment_option' => 'without_writeoff',
'amount_original' => -$amount_total,
// 'amount'=>-$amount_total,
'amount_unreconciled' => -$amount_total,
'voucher_id' => $voucherResult,//$voucher_id,
'partner_id' => $invoiceDatas['partner_id'][0],
'account_id' => $invoiceDatas['account_id'][0],
'move_line_id' => $invoice_object_line[0]["id"],
'type' => 'cr'
);
$createVoucherLine = $OERP->create($voucherLineItems, 'account.voucher.line');
$performa_voucher_result = $OERP->workflow('account.voucher', 'proforma_voucher', intval($voucherResult));
$invoiceMovId = $OERP->searchread(array(array('id','=',$createRefund)),'account.invoice' );
$button_validate_result = $OERP->button_click('account.move', 'button_validate', $invoiceMovId[0]["move_id"][0]);
I figured it out the answer to create an invoice refund here is the code if it helps anyone
$invoiceId = $_REQUEST["invoiceID"];
$OERP = new OpenERP();
$OERPUserID = $OERP->login($_SESSION['OERP-username'], $_SESSION['OERP-password']);
$invoiceData = $OERP->searchread(array(array('id','=',$invoiceId )), 'account.invoice');
$invoiceDatas = array();
foreach($invoiceData as $data)
{
$invoiceDatas["amount_total"] = $data["amount_total"];
$invoiceDatas["partner_id"] = $data["partner_id"];
$invoiceDatas["account_id"] = $data["account_id"];
$invoiceDatas["invoice_line"] = $data["invoice_line"];
$invoiceDatas["reference"] = $data["reference"];
$invoiceDatas["period_id"] = $data["period_id"];
}
$invoiceLineData = $OERP->searchread(array(array('invoice_id','=', intval($invoiceId) )), 'account.invoice.line');
foreach($invoiceLineData as $data)
{
$invoiceLine["product_id"] = $data["product_id"];
$invoiceLine["price_unit"] = $data["price_unit"];
}
//create Refund
$createRefundParams = array(
'date_invoice' => date('Y/m/d'),
'partner_id' => $invoiceDatas["partner_id"][0],
'journal_id' => 3,// $journalId,
'account_id' => $invoiceDatas["account_id"][0],
// 'reference'=>$invoiceDatas["reference"],
'name'=>'front end refundi',
'type'=>'out_refund' // dallon invoicen nga refund
);
$createRefund = $OERP->create($createRefundParams, 'account.invoice');
$invoiceProduct = array(
'invoice_id'=>$createRefund,
'product_id'=>$invoiceLine["product_id"][0],
'name'=>'refund',//$invoiceLine["product_id"][1],
'account_id'=>19,
'price_unit'=>$invoiceLine["price_unit"]
);
$createRefundLines = $OERP->create($invoiceProduct,"account.invoice.line");
$validateRefund = $OERP->workflow('account.invoice', 'invoice_open', $createRefund);
//================ Payments ===========================
$amount_total = -$invoiceDatas['amount_total'];
$newInvoice = $OERP -> searchread(array(array('id','=',$createRefund)),'account.invoice' );
$moveId = array();
foreach($newInvoice as $data)
{
$moveId["move_id"] = $data["move_id"];
}
$createVoucher = array(
'date' => date('Y/m/d'),
'partner_id' => $invoiceDatas['partner_id'][0],
'amount' =>$amount_total ,
'journal_id' => 7,// $journalId,
'account_id' => 25,
'period_id' => $invoiceDatas['period_id'][0],
'type' => 'receipt'
);
// $createRefund
$voucherResult = $OERP->create($createVoucher, 'account.voucher');
$invoice_object_line = $OERP->searchread(array(array('move_id', '=', $moveId["move_id"][0])), 'account.move.line');
$voucherLineItems = array(
//notice that amount values are positive since there is an extra minus in variable intialization
'journal_id' => 7,// $journalId,
'period_id' => $invoiceDatas['period_id'][0],
'date' => date('Y/m/d'),
'date_due' => date('Y/m/d'),
'name' => 'Payment for refund',
'payment_option' => 'without_writeoff',
'amount_original' => -$amount_total,
'amount'=>-$amount_total,
'amount_unreconciled' => -$amount_total,
'voucher_id' => $voucherResult,//$voucher_id,
'partner_id' => $invoiceDatas['partner_id'][0],
'account_id' => $invoiceDatas['account_id'][0],
'move_line_id' => $invoice_object_line[0]["id"],
'type' => 'dr'
);
$createVoucherLine = $OERP->create($voucherLineItems, 'account.voucher.line');
$performa_voucher_result = $OERP->workflow('account.voucher', 'proforma_voucher', intval($voucherResult));
$invoiceMovId = $OERP->searchread(array(array('id','=',$createRefund)),'account.invoice' );
$button_validate_result = $OERP->button_click('account.move', 'button_validate', $invoiceMovId[0]["move_id"][0]);

nHibernate - Adding aggregate functions in .select

I am trying to implement a business formula in QueryOver.
POorder.Estimate is a calculated field and I need to get
ToDateOrderAmount = POrder.Estimate - Sum(PODist.Field1) - Sum(PODisTaxRebate.Field1 + PODisTaxRebate.Field2)
So I need to write a query. What I have now is:
var reportModels =
Session.QueryOver<Domain.Model.Purchasing.Vendor>(() => v)
.Left.JoinQueryOver(() => v.Invoices, () => invoice)
.Left.JoinQueryOver(() => invoice.PurchaseOrder, () => poOrder)
.Left.JoinQueryOver(() => poOrder.PurchaseOrderDistributions, () => poDistribution)
.Left.JoinQueryOver(() => poDistribution.TaxRebate, () => poTaxRebate)
.SelectList(
list =>
list.Select(() => v.Number).WithAlias(() => varptModel.VendorNumber)
.Select(() => v.TypeCode.Code).WithAlias(() => varptModel.VendorType)
.Select(() => v.Name).WithAlias(() => varptModel.VendorName)
.Select(() => v.PurchasingContactPhoneNumber + "-Ext." + v.PurchasingContactPhoneNumberExt).WithAlias(() => varptModel.Phone)
.Select(() => v.Address).WithAlias(() => varptModel.Address)
.Select(() => invFiscalYear.Year).WithAlias(() => varptModel.Year)
.Select(() => invoice.TotalAmount).WithAlias(() => varptModel.InvoiceToDate)
.Select(() => invoice.AmountPaidToDate).WithAlias(() => varptModel.PaymentToDate)
.Select(() => poOrder.Estimate).WithAlias(() => varptModel.OrdersToDate)
.Select(() => poOrder.Estimate - Sum(poDistribution.Field1) - Sum(poTaxRebate.Discount1 + poTaxRebate.Discount2) )
).List();
But this is not right. What should I change it to?
I tried many things and found this working
.Select(Projections.SqlFunction(new VarArgsSQLFunction("", "+", ""),
NHibernateUtil.Double,
Projections.SqlFunction(new VarArgsSQLFunction("", "+", ""),
NHibernateUtil.Double,
Projections.Sum(Projections.SqlFunction("coalesce", NHibernateUtil.Double, Projections.Property(() => invoiceLineItem.Expense), Projections.Constant(0))),
Projections.Sum(Projections.SqlFunction("coalesce", NHibernateUtil.Double, Projections.Property(() => invitemTaxRebate.Rebate1Expense), Projections.Constant(0)))),
Projections.Sum(Projections.SqlFunction("coalesce", NHibernateUtil.Double, Projections.Property(() => invitemTaxRebate.Rebate2Expense), Projections.Constant(0)))))
.WithAlias(() => varptModel.ToDateInvoices)
which gave me this in SQL
sum(coalesce(invoicelin8_.Expense, 0 )) + sum(coalesce(invitemtax9_.Rebate1Expense, 0 )) + sum(coalesce(invitemtax9_.Rebate2Expense, 0 ))
I added Coalesce as when we add or subtract values with null value, all values becomes null in result. Just a hint for new ones.

NHibernate fetch with transformation

im trying to query using QueryOver and im trying to do some transformation with fetching.
But im hitting error
HSPTransactionDto hspTransactionDto = null;
var hspTransactionDtoList =
Session.QueryOver<Transaction>()
.Where(x => x.TransactionStatus == TransactionStatus.Draft)
.Fetch(x => x.HealthServiceProvider).Eager
.Fetch(x => x.HealthMaintenanceOrganization).Eager
.SelectList(list => list
.Select(x => x.Id).WithAlias(() => hspTransactionDto.Id)
.Select(x => x.Version).WithAlias(() => hspTransactionDto.Version)
.Select(x => x.HealthServiceProvider.Id).WithAlias(() => hspTransactionDto.HSPId)
.Select(x => x.HealthServiceProvider.Name).WithAlias(() => hspTransactionDto.HSPName)
.Select(x => x.HealthMaintenanceOrganization.Id).WithAlias(() => hspTransactionDto.HMOId)
.Select(x => x.HealthMaintenanceOrganization.Name).WithAlias(() => hspTransactionDto.HMOName)
.Select(x => x.HSPPatientCode).WithAlias(() => hspTransactionDto.HSPPatientCode)
.Select(x => x.PatientFirstName).WithAlias(() => hspTransactionDto.PatientFirstName)
.Select(x => x.PatientMiddleName).WithAlias(() => hspTransactionDto.PatientMiddleName)
.Select(x => x.PatientLastName).WithAlias(() => hspTransactionDto.PatientLastName)
)
.TransformUsing(Transformers.AliasToBean<HSPTransactionDto>()).List<HSPTransactionDto>();
return hspTransactionDtoList;
anyone can help?
actually found the answer just need to put some alias so i ended up with
HSPTransactionDto hspTransactionDto = null;
HealthMaintenanceOrganization hmoAlias = null;
HealthServiceProvider hspAlias = null;
var hspTransactionDtoList =
Session.QueryOver<Transaction>()
.Where(a => a.TransactionStatus == TransactionStatus.Draft)
.Fetch(b => b.HealthServiceProvider).Eager
.Fetch(c => c.HealthMaintenanceOrganization).Eager
.JoinAlias(x=> x.HealthMaintenanceOrganization,() => hmoAlias)
.JoinAlias(x => x.HealthServiceProvider, () => hspAlias)
.SelectList(list => list
.Select(x => x.Id).WithAlias(() => hspTransactionDto.Id)
.Select(x => x.Version).WithAlias(() => hspTransactionDto.Version)
.Select(x => hspAlias.Id).WithAlias(() => hspTransactionDto.HSPId)
.Select(x => hspAlias.Name).WithAlias(() => hspTransactionDto.HSPName)
.Select(x => hmoAlias.Id).WithAlias(() => hspTransactionDto.HMOId)
.Select(x => hmoAlias.Name).WithAlias(() => hspTransactionDto.HMOName)
.Select(x => x.HSPPatientCode).WithAlias(() => hspTransactionDto.HSPPatientCode)
.Select(x => x.PatientFirstName).WithAlias(() => hspTransactionDto.PatientFirstName)
.Select(x => x.PatientMiddleName).WithAlias(() => hspTransactionDto.PatientMiddleName)
.Select(x => x.PatientLastName).WithAlias(() => hspTransactionDto.PatientLastName)
)
.TransformUsing(Transformers.AliasToBean<HSPTransactionDto>()).List<HSPTransactionDto>();
return hspTransactionDtoList;
anyone know a cleaner way?
I think you don't need to use Fetch, because you've used Select for selective properties and it's grouped with DTO:
HSPTransactionDto hspTransactionDto = null;
HealthMaintenanceOrganization hmoAlias = null;
HealthServiceProvider hspAlias = null;
var hspTransactionDtoList =
Session.QueryOver<Transaction>()
.Where(a => a.TransactionStatus == TransactionStatus.Draft)
.JoinAlias(x=> x.HealthMaintenanceOrganization,() => hmoAlias)
.JoinAlias(x => x.HealthServiceProvider, () => hspAlias)
.SelectList(list => list
.Select(x => x.Id).WithAlias(() => hspTransactionDto.Id)
.Select(x => x.Version).WithAlias(() => hspTransactionDto.Version)
.Select(x => hspAlias.Id).WithAlias(() => hspTransactionDto.HSPId)
.Select(x => hspAlias.Name).WithAlias(() => hspTransactionDto.HSPName)
.Select(x => hmoAlias.Id).WithAlias(() => hspTransactionDto.HMOId)
.Select(x => hmoAlias.Name).WithAlias(() => hspTransactionDto.HMOName)
.Select(x => x.HSPPatientCode).WithAlias(() => hspTransactionDto.HSPPatientCode)
.Select(x => x.PatientFirstName).WithAlias(() => hspTransactionDto.PatientFirstName)
.Select(x => x.PatientMiddleName).WithAlias(() => hspTransactionDto.PatientMiddleName)
.Select(x => x.PatientLastName).WithAlias(() => hspTransactionDto.PatientLastName)
)
.TransformUsing(Transformers.AliasToBean<HSPTransactionDto>()).List<HSPTransactionDto>();
return hspTransactionDtoList;