optional include with entity framework - entity-framework

I'm working on a manager. Depending on the conditions some include must be enforced in order to get eager loading. But sometime I don't want all the data so the includes should not be applied.
This is what I've got so far.
//INFO : public partial class Entities : DbContext
var Database = new Entities();
var result = Database.Department;
if (includeHospitalEmployee) { result.Include(a => a.HospitalEmployee); }
if (includeQuickScans) { result.Include(a => a.QuickScan); }
return result;
This doesn't work. The includes aren't loaded, although the includebooleans are set to true. Query results in;
SELECT
[Extent1].[Code] AS [Code],
[Extent1].[Discipline] AS [Discipline],
[Extent1].[FinancialCode] AS [FinancialCode],
[Extent1].[Name] AS [Name],
[Extent1].[DepartmentManagerId] AS [DepartmentManagerId],
[Extent1].[Show] AS [Show],
[Extent1].[Id] AS [Id]
FROM [dbo].[Department] AS [Extent1]
But strange enough if i do this, all include are working
//INFO : public partial class Entities : DbContext
var Database = new Entities();
var result = this.businessManagersFactory.Database.Department.Include(a => a.QuickScan);;
if (includeHospitalEmployee) { result.Include(a => a.HospitalEmployee); }
if (includeQuickScans) { result.Include(a => a.QuickScan); }
return result;
see the query
SELECT
[Project1].[C1] AS [C1],
[Project1].[Code] AS [Code],
[Project1].[Discipline] AS [Discipline],
[Project1].[FinancialCode] AS [FinancialCode],
[Project1].[Name] AS [Name],
[Project1].[DepartmentManagerId] AS [DepartmentManagerId],
[Project1].[Show] AS [Show],
[Project1].[Id] AS [Id],
[Project1].[C2] AS [C2],
[Project1].[Id1] AS [Id1],
[Project1].[StartDateTime] AS [StartDateTime],
[Project1].[EndDateTime] AS [EndDateTime],
[Project1].[Shared] AS [Shared],
[Project1].[ScanStatus] AS [ScanStatus],
[Project1].[Title] AS [Title],
[Project1].[Count] AS [Count],
[Project1].[Comment] AS [Comment],
[Project1].[HospitalEmployeeId] AS [HospitalEmployeeId],
[Project1].[DepartmentId] AS [DepartmentId]
FROM ( SELECT
[Extent1].[Code] AS [Code],
[Extent1].[Discipline] AS [Discipline],
[Extent1].[FinancialCode] AS [FinancialCode],
[Extent1].[Name] AS [Name],
[Extent1].[DepartmentManagerId] AS [DepartmentManagerId],
[Extent1].[Show] AS [Show],
[Extent1].[Id] AS [Id],
1 AS [C1],
[Extent2].[Id] AS [Id1],
[Extent2].[StartDateTime] AS [StartDateTime],
[Extent2].[EndDateTime] AS [EndDateTime],
[Extent2].[Shared] AS [Shared],
[Extent2].[ScanStatus] AS [ScanStatus],
[Extent2].[Title] AS [Title],
[Extent2].[Count] AS [Count],
[Extent2].[Comment] AS [Comment],
[Extent2].[HospitalEmployeeId] AS [HospitalEmployeeId],
[Extent2].[DepartmentId] AS [DepartmentId],
CASE WHEN ([Extent2].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2]
FROM [dbo].[Department] AS [Extent1]
LEFT OUTER JOIN [dbo].[QuickScan] AS [Extent2] ON [Extent1].[Code] = [Extent2].[DepartmentId]
) AS [Project1]
ORDER BY [Project1].[Code] ASC, [Project1].[C2] ASC
Why is this behaviour and how to get it working properly?
regards

I don't have access to Visual Studio to confirm but you will probably find that assigning the return from the call to Include will sort it - it will be something like a QueryObject that implements IQueryable
var Database = new Entities();
IQueryable<Department> result = Database.Departments;
if (includeHospitalEmployee) { result = result.Include(a => a.HospitalEmployee); }
if (includeQuickScans) { result = result.Include(a => a.QuickScan); }
return result;

Related

How to convert sql query to query builder typeorm format

1: This is sql query
INSERT INTO allocation (
effort, "startDate", "endDate", "employeeId", "projectId"
)
SELECT Distinct
request_allocation_detail.effort,
request_allocation_detail."startDate",
request_allocation_detail."endDate",
request_allocation_detail."employeeId",
request_allocation."projectId"
From
public.request_allocation
inner join public.request_allocation_detail ON request_allocation_detail."requestAllocationId" = request_allocation.id
where
request_allocation_detail.id = '${currentRequestDetailId}'
2: this is query builder using typeorm but it not work:
=>Create query builder and try to insert into using select with typeorm
const db= this.allocationRepository
.createQueryBuilder('allocation')
.insert()
.into('allocation')
.values(['effort', 'startDate', 'endDate', 'employeeId', 'projectId'])
.select([
'request_allocation_detail.effort',
'request_allocation_detail."startDate"',
'request_allocation_detail."endDate"',
'request_allocation_detail."employeeId"',
'request_allocation."projectId"',
])
.distinct()
.from('request_allocation', 'request_allocation')
.innerJoinAndSelect(
'request_allocation_detail',
'request_allocation_detail',
'request_allocation_detail.id = request_allocation.id'
)
.where('request_allocation_detail.id = :id', {
id: currentRequestDetailId,
});
Please help me how to resolve it
First i separate sql query to 2 phase: select and insert:
Second: i write querybuilder with typeorm to command select:
const (*) [subQuery, params] = this.createQueryBuilder(
'request_allocation_detail'
)
.innerJoin(
'request_allocation',
'request_allocation',
'request_allocation_detail."requestAllocationId" = request_allocation.id'
)
.where('request_allocation_detail.id = :id', {
id: currentRequestDetailId,
})
.select([
'request_allocation_detail.effort',
'request_allocation_detail.startDate',
'request_allocation_detail.endDate',
'request_allocation_detail."employeeId"',
'request_allocation."projectId"',
])
.getQueryAndParameters();
Next i return with command insert into with command query in typeorm:
return this.query(
`
INSERT INTO allocation (here is column i need to add data from *)${subQuery}`,
params
);

Spring data r2dbc and group by

I am using the DatabaseClient to perform my sql queries and I don't see how I can do a group by:
databaseClient.select()
.from( myClass.class )
.matching( where( "row_1" ).is( "value_1" ) )
//group by row_2 ...
.orderBy( Sort.Order.desc( "row_3" ) )
.page( pageable )
.fetch()
.all();
A workaround solution using sql directly.
public Flux<Map<Object, Object>> countByStatus() {
return this.databaseClient
.sql("SELECT count(*) as cnt, status FROM posts group by status")
.map((row, rowMetadata) -> {
Long cnt = row.get("cnt", Long.class);
Post.Status s = row.get("status", Post.Status.class);
return Map.<Object, Object>of("cnt", cnt, "status", s);
})
.all();
}
Check the complete codes.

pg8000.core.ProgrammingError: 'could not determine data type of parameter $2'

I'm using pg.8000 (Postgres) and trying to run the following SELECT query
cursor.execute(
"""
SELECT orders.name, orders.order_price, orders.selling_price, orders.earnings
FROM member, orders
WHERE member.id=orders.member_id
AND member.name = %s
""",
member_username
)
Where member.username is a String.
But I am getting the following error.
pg8000.core.ProgrammingError: ('ERROR', 'ERROR', '42P18', 'could not determine data type of parameter $2', 'postgres.c', '1350', 'exec_parse_message', '', '')
However, when I run same query using GUI tool, everything runs fine and I get the results. What is the problem?
You passed the parameter wrong, you should give a tuple, a list or a dictionary
Example with a tuple:
cursor.execute(
"""
SELECT orders.name, orders.order_price, orders.selling_price, orders.earnings
FROM member, orders
WHERE member.id=orders.member_id
AND member.name = %s
""",
(member_username,)
)
Example with a list:
cursor.execute(
"""
SELECT orders.name, orders.order_price, orders.selling_price, orders.earnings
FROM member, orders
WHERE member.id=orders.member_id
AND member.name = %s
""",
[member_username]
)
Example with a dictionary:
cursor.execute(
"""
SELECT orders.name, orders.order_price, orders.selling_price, orders.earnings
FROM member, orders
WHERE member.id=orders.member_id
AND member.name = %(mname)s
""",
{'mname' : member_username}
)
http://initd.org/psycopg/docs/usage.html#query-parameters

JPA optimistic lock can't get the latest version

I am using the JPA's optimistic lock with spring data jpa and using spring retry for ConcurrencyFailureException, but something occurs that i can't understand.
my test code just like below:
#Repository
public interface AccountRepo extends JpaRepository<Account, String>, JpaSpecificationExecutor<Account> {
#Lock(LockModeType.OPTIMISTIC)
#Query(value = "select a from Account a where a.id = :id")
Account findOne(#Param("id") String id);
}
--------------------------------------------------------------------
#Service
public class AccountService {
#Qualifier("accountRepo")
#Autowired
private AccountRepo accountRepo;
#Transactional(value = "transactionManager", isolation = Isolation.READ_COMMITTED)
public Account saveOne(Account account){
return accountRepo.save(account);
}
public Account findOne(String id){
return accountRepo.findOne(id);
}
}
----------------------------------------------------------------------
#Transactional(value = "transactionManager", isolation = Isolation.READ_COMMITTED)
#Retryable(value = {ConcurrencyFailureException.class}, backoff = #Backoff(delay = 3000))
public void testOptimistic(){
Account account = accountService.findOne("abee19e08d3d4ee79d9f831c3ed78344");
account.setHistoryIncome(new BigDecimal("3300"));
account.setTodayTotalIncome(new BigDecimal("3300"));
account.setTodayOnlineIncome(new BigDecimal("3300"));
account.setAvaliableAmount(new BigDecimal("3300"));
accountService.saveOne(account);
AccountOperRecord accountOperRecord = new AccountOperRecord();
accountOperRecord.setId(BuildNoUtil.buildAccountOperRecordId());
accountOperRecord.setTrxType(TrxTypeEnum.EXPENSE.name());
accountOperRecord.setAvaliableAmount(account.getAvaliableAmount());
accountOperRecord.setOperAmount(new BigDecimal("100"));
accountOperRecord.setOrderId("4028b8815c813d64015c813e17f50000");
accountOperRecord.setOutTradeNo("2015061121001004400068549373");
accountOperRecord.setAccountId("abee19e08d3d4ee79d9f831c3ed78344");
accountOperRecordService.saveOne(accountOperRecord);
}
----------------------------------------------------------------------
#Controller
public class TestController extends BaseController {
#RequestMapping(value = "testOptimistic")
#ResponseBody
public JSONObject testOptimisticLock(){
JSONObject result = new JSONObject();
conjunctionService.testOptimistic();
result.put("code", "success");
return result;
}
}
i added a breakpoint at Account account = accountService.findOne("abee19e08d3d4ee79d9f831c3ed78344");, then i run a transaction in mysql to change the version of Account.
After that, the testOptimistic method throws the ConcurrencyFailureException and the method retried, in my opinion, it will success the next time but it failed again, finally it success at the third time, i just can not understand.
the logs of Hibernate SQL showed below
Hibernate: select account0_.id as id1_0_, account0_.create_time as create_t2_0_, account0_.creater as creater3_0_, account0_.edit_time as edit_tim4_0_, account0_.editor as editor5_0_, account0_.remark as remark6_0_, account0_.address as address7_0_, account0_.avaliable_amount as avaliabl8_0_, account0_.email as email9_0_, account0_.history_expense as history10_0_, account0_.history_income as history11_0_, account0_.merchant_name as merchan12_0_, account0_.name as name13_0_, account0_.phone as phone14_0_, account0_.settled_amount as settled15_0_, account0_.settling_amount as settlin16_0_, account0_.splited_amount as splited17_0_, account0_.today_offline_income as today_o18_0_, account0_.today_online_income as today_o19_0_, account0_.today_total_income as today_t20_0_, account0_.version as version21_0_ from account account0_ where account0_.id=?
Hibernate: select accountope0_.id as id1_1_0_, accountope0_.account_id as account_2_1_0_, accountope0_.avaliable_amount as avaliabl3_1_0_, accountope0_.oper_amount as oper_amo4_1_0_, accountope0_.order_id as order_id5_1_0_, accountope0_.out_trade_no as out_trad6_1_0_, accountope0_.remit_id as remit_id7_1_0_, accountope0_.settle_id as settle_i8_1_0_, accountope0_.split_batch_id as split_ba9_1_0_, accountope0_.trx_type as trx_typ10_1_0_ from account_oper_record accountope0_ where accountope0_.id=?
Hibernate: insert into account_oper_record (account_id, avaliable_amount, oper_amount, order_id, out_trade_no, remit_id, settle_id, split_batch_id, trx_type, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: update account set avaliable_amount=?, history_income=?, today_online_income=?, today_total_income=?, version=? where id=? and version=?
Hibernate: select account0_.id as id1_0_, account0_.create_time as create_t2_0_, account0_.creater as creater3_0_, account0_.edit_time as edit_tim4_0_, account0_.editor as editor5_0_, account0_.remark as remark6_0_, account0_.address as address7_0_, account0_.avaliable_amount as avaliabl8_0_, account0_.email as email9_0_, account0_.history_expense as history10_0_, account0_.history_income as history11_0_, account0_.merchant_name as merchan12_0_, account0_.name as name13_0_, account0_.phone as phone14_0_, account0_.settled_amount as settled15_0_, account0_.settling_amount as settlin16_0_, account0_.splited_amount as splited17_0_, account0_.today_offline_income as today_o18_0_, account0_.today_online_income as today_o19_0_, account0_.today_total_income as today_t20_0_, account0_.version as version21_0_ from account account0_ where account0_.id=?
Hibernate: select accountope0_.id as id1_1_0_, accountope0_.account_id as account_2_1_0_, accountope0_.avaliable_amount as avaliabl3_1_0_, accountope0_.oper_amount as oper_amo4_1_0_, accountope0_.order_id as order_id5_1_0_, accountope0_.out_trade_no as out_trad6_1_0_, accountope0_.remit_id as remit_id7_1_0_, accountope0_.settle_id as settle_i8_1_0_, accountope0_.split_batch_id as split_ba9_1_0_, accountope0_.trx_type as trx_typ10_1_0_ from account_oper_record accountope0_ where accountope0_.id=?
Hibernate: insert into account_oper_record (account_id, avaliable_amount, oper_amount, order_id, out_trade_no, remit_id, settle_id, split_batch_id, trx_type, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: update account set avaliable_amount=?, history_income=?, today_online_income=?, today_total_income=?, version=? where id=? and version=?
Hibernate: select version from account where id =?
Hibernate: select account0_.id as id1_0_, account0_.create_time as create_t2_0_, account0_.creater as creater3_0_, account0_.edit_time as edit_tim4_0_, account0_.editor as editor5_0_, account0_.remark as remark6_0_, account0_.address as address7_0_, account0_.avaliable_amount as avaliabl8_0_, account0_.email as email9_0_, account0_.history_expense as history10_0_, account0_.history_income as history11_0_, account0_.merchant_name as merchan12_0_, account0_.name as name13_0_, account0_.phone as phone14_0_, account0_.settled_amount as settled15_0_, account0_.settling_amount as settlin16_0_, account0_.splited_amount as splited17_0_, account0_.today_offline_income as today_o18_0_, account0_.today_online_income as today_o19_0_, account0_.today_total_income as today_t20_0_, account0_.version as version21_0_ from account account0_ where account0_.id=?
Hibernate: select accountope0_.id as id1_1_0_, accountope0_.account_id as account_2_1_0_, accountope0_.avaliable_amount as avaliabl3_1_0_, accountope0_.oper_amount as oper_amo4_1_0_, accountope0_.order_id as order_id5_1_0_, accountope0_.out_trade_no as out_trad6_1_0_, accountope0_.remit_id as remit_id7_1_0_, accountope0_.settle_id as settle_i8_1_0_, accountope0_.split_batch_id as split_ba9_1_0_, accountope0_.trx_type as trx_typ10_1_0_ from account_oper_record accountope0_ where accountope0_.id=?
Hibernate: insert into account_oper_record (account_id, avaliable_amount, oper_amount, order_id, out_trade_no, remit_id, settle_id, split_batch_id, trx_type, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: update account set avaliable_amount=?, history_income=?, today_online_income=?, today_total_income=?, version=? where id=? and version=?
Hibernate: select version from account where id =?
Hibernate: select version from account where id =?
you can see that select version from account where id =? execute two times at the third time, anyone can explain this?!
Thank you very much!

Odoo One2many relation with VIEW table in postgresql

I have the following report model:
class crm_purchased_products(models.Model):
_name = "crm.purchased_products"
_description = "Most purchased products report"
_auto = False
partner_id = fields.Many2one('res.partner', string='Customer')
product_id = fields.Many2one('product.product', string='Product')
invoice_qty = fields.Integer('Number of invoices')
quantity = fields.Integer('Quantity')
total_amount_untaxed = fields.Float(string='Total amount', digits=dp.get_precision('Account'))
def init(self, cr):
tools.drop_view_if_exists(cr, self._table)
_query = """CREATE OR REPLACE VIEW crm_purchased_products AS (
SELECT ail.partner_id AS partner_id, ail.product_id AS product_id,
COUNT(ail.invoice_id) AS invoice_qty, SUM(ail.quantity) AS quantity,
SUM(ail.price_subtotal) AS total_amount_untaxed, MAX(ai.date_invoice) AS last_purchase,
(MAX(ai.date_invoice) - MIN(ai.date_invoice))/COUNT(ail.invoice_id) AS days_between_purchases
FROM account_invoice_line AS ail
JOIN account_invoice AS ai ON ail.invoice_id = ai.id
WHERE ai.type = 'out_invoice' AND ai.state IN ('open','paid')
GROUP BY ail.partner_id, ail.product_id HAVING ail.product_id > 0 ORDER BY ail.partner_id ASC
);
"""
def search(self, cr, uid, args, offset=0, limit=None, order=None,context=None, count=False):
return super(crm_purchased_products, self).search(cr, uid, args=args, offset=offset, limit=limit, order=order,
context=context, count=count)
crm_purchased_products()
I want to insert as a tree field in res.partner form view to show only the products associated to the contact:
<page name="internal_notes" string="Internal Notes">
<field name="purchased_products">
<tree string="Most purchased products">
<field name="partner_id" invisible="1"/>
<field name="product_id"/>
<field name="invoice_qty"/>
<field name="quantity"/>
<field name="total_amount_untaxed"/>
</tree>
</field>
</page>
But, when I try to relate it from res.partner:
purchased_products = fields.One2many('crm.purchased_products', 'partner_id', string='Purchased products', readonly=True, copy=True)
I get this error:
ProgrammingError: relation "crm_purchased_products" does not exist
LINE 1: SELECT "crm_purchased_products".id FROM "crm_purchased_produ...
ID field is auto added to all models from models.Model, so you must get it. Try this:
def init(self, cr):
tools.drop_view_if_exists(cr, self._table)
_query = """CREATE OR REPLACE VIEW crm_purchased_products AS (
SELECT row_number() OVER () AS id, ail.partner_id AS partner_id, ail.product_id AS product_id,
COUNT(ail.invoice_id) AS invoice_qty, SUM(ail.quantity) AS quantity,
SUM(ail.price_subtotal) AS total_amount_untaxed, MAX(ai.date_invoice) AS last_purchase,
(MAX(ai.date_invoice) - MIN(ai.date_invoice))/COUNT(ail.invoice_id) AS days_between_purchases
FROM account_invoice_line AS ail
JOIN account_invoice AS ai ON ail.invoice_id = ai.id
WHERE ai.type = 'out_invoice' AND ai.state IN ('open','paid')
GROUP BY row_number() OVER (), ail.partner_id, ail.product_id HAVING ail.product_id > 0 ORDER BY ail.partner_id ASC
);
"""