CosmosQueryableExtensions.FromSqlRaw generates undesired sub query - entity-framework-core

I have a scenario where I need to create raw query towards CosmosDb. For the sake of this question, I have a simplified call:
CosmosQueryableExtensions.FromSqlRaw(db.ProjectFolders, "SELECT VALUE c FROM c WHERE c.Site = \"mysite\"")
but it generates query with undesired subquery:
info: Microsoft.EntityFrameworkCore.Database.Command[30102]
Executed ReadNext (784.3342 ms, 2.85 RU) ActivityId='3f8b0dfd-09f5-4fd3-99e3-3bae8edbe06e', Container='Items', Partition='?', Parameters=[]
SELECT c
FROM (
SELECT VALUE c FROM c WHERE c.Site = "mysite"
) c
Is this by design, irrelevant, or am I doing something wrong?

Explaination :- FromSQLRow generates query with in subquery and its by design.
Composing query with LINQ, EF Core will consider passed LINQ SQL query as subquery over the database. Composing SQL query with in LINQ starts with SELECT but can't have SQL like features such as
Trailing semicolon (;)
ORDER BY clause
References :-
https://learn.microsoft.com/en-us/ef/core/querying/sql-queries#composing-with-linq
Include with FromSqlRaw and stored procedure in EF Core 3.1
How do I access the VALUE using CosmosQueryableExtensions

Related

updating table rows in postgres using subquery with jooq

I would like to execute and update similar to this:
UPDATE dummy
SET customer=subquery.customer,
address=subquery.address,
partn=subquery.partn
FROM (SELECT address_id, customer, address, partn
FROM dummy) AS subquery
WHERE dummy.address_id=subquery.address_id;
Taken from this answer: https://stackoverflow.com/a/6258586/411965
I found this and wondered if this can auto converted to jooq fluent syntax.
What is the equivalent jooq query? specifically, how do I perform the outer when referencing the subquery?
Assuming you're using code generation, do it like this:
Table<?> subquery = table(
select(
DUMMY.ADDRESS_ID,
DUMMY.CUSTOMER,
DUMMY.ADDRESS,
DUMMY.PARTN
)
.from(DUMMY)
).as("subquery");
ctx.update(DUMMY)
.set(DUMMY.CUSTOMER, subquery.field(DUMMY.CUSTOMER))
.set(DUMMY.ADDRESS, subquery.field(DUMMY.ADDRESS))
.set(DUMMY.PARTN, subquery.field(DUMMY.PARTN))
.from(subquery)
.where(DUMMY.ADDRESS_ID.eq(subquery.field(DUMMY.ADDRESS_ID)))
.execute();
Of course, the query makes no sense it is, because you're just going to touch every row without modifying it, but since you copied the SQL from another answer, I'm assuming your subquery's dummy table is really something else.

Table Valued Functions in EF Core

I am using EF Core 1.1 and have a query like
var list=from l in context.Users
where l.SomeProp==someVal
select l;
I have a UDF which returns a table of Id's and I basically want to generate the following query:
select * from Users where SomeProp=#someVal and SomeId in (select id from fn_myfunc(#id))
Is this possible to do?
I think you are limited to running a raw SQL query against the database to be able to use a table valued function. For example:
var query = #"SELECT * FROM Users WHERE SomeProp = {0}
AND SomeId IN (SELECT id FROM fn_myfunc({1})";
var users = context.Users
.FromSql(query, someProp, someId)
.ToList();
There are some limitations with this method. From the docs:
SQL queries can only be used to return entity types that are part of your model. There is an enhancement on our backlog to enable returning ad-hoc types from raw SQL queries.
The SQL query must return data for all properties of the entity type.
The column names in the result set must match the column names that properties are mapped to. Note this is different from EF6.x where property/column mapping was ignored for raw SQL queries and result set column names had to match the property names.
The SQL query cannot contain related data. However, in many cases you can compose on top of the query using the Include operator to return related data.
You can return related data (i.e. Include) like this:
var users = context.Users
.FromSql(query, someProp, someId)
.Include(u => u.OtherThings)
.ToList();
If you need to do anything more complex, then you would need to either drop down to using raw data access (like ADO.Net) or another ORM. I know people who use EF Core for the bulk of the work and then occasionally drop into Dapper for performance or raw SQL that doesn't suit EF.

Getting a Result Set's Column Names via T-SQL

Is there a way to get the column names that an arbitrary query will return using just T-SQL that works with pre-2012 versions of Microsoft SQL Server?
What Doesn't Work:
sys.columns and INFORMATION_SCHEMA.COLUMNS work great for obtaining the column list for tables or views but don't work with arbitrary queries.
sys.dm_exec_describe_first_result would be perfect except that this management function was added in SQL Server 2012. What I'm writing needs to be backwards compatible to SQL Server 2005.
A custom CLR function could easily provide this information but introduces deployment complexities on the server side. I'd rather not go this route.
Any ideas?
So long as the arbitrary query qualifies to be used as a nested query (i.e. no CTEs, unique column names, etc.), this can be achieved by loading the query's metadata into a temp table, then retrieving column details via sys.tables:
SELECT TOP 0 * INTO #t FROM (query goes here) q
SELECT name FROM tempdb.sys.columns WHERE object_id = OBJECT_ID('tempdb..#t')
DROP TABLE #t
Thanks to #MartinSmith's for suggesting this approach!

JPQL / JPA query to order entities based on the greatest/maximum of two columns?

I need something similar to this SQL query:
SELECT * FROM foo f ORDER BY GREATEST(f.bar_date, f.baz_date)
As not all RDBMS systems support the GREATEST function, ideally I would like the JPA implementation to generate the correct SQL query for the underlying database. The databases that I am targetting are Oracle, SQL Server, and PostgreSQL.
JPQL allows the FUNCTION operator to call a database function.
Oracle and Postgres support GREATEST, I don't think SQL Server does, so for it you may be able to write your own function.
You could also use a CASE function with >.
To put this a little more concrete - you could do this in JPQL with the CASE statement, which is supported since JPA 2.0. I've omitted the _date suffixes for brevity.
SELECT * FROM foo f ORDER BY CASE WHEN f.bar > f.baz THEN f.bar ELSE f.baz END
I've used CASE function.
Via criteria builder it looks like:
CriteriaQuery<?> query = ...
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
query.orderBy(builder.selectCase().when(builder.greaterThan(pathToBarDate, pathToBazDate),pathToBarDate).otherwise(pathToBazDate));
In JPQL it should look like
ORDER BY
CASE WHEN (f.bar_date>f.baz_date) THEN f.bar_date
ELSE f.baz_date

Is it possible to use CASE with IN?

I'm trying to construct a T-SQL statement with a WHERE clause determined by an input parameter. Something like:
SELECT * FROM table
WHERE id IN
CASE WHEN #param THEN
(1,2,4,5,8)
ELSE
(9,7,3)
END
I've tried all combination of moving the IN, CASE etc around that I can think of. Is this (or something like it) possible?
try this:
SELECT * FROM table
WHERE (#param='??' AND id IN (1,2,4,5,8))
OR (#param!='??' AND id in (9,7,3))
this will have a problem using an index.
The key with a dynamic search conditions is to make sure an index is used, instead of how can I easily reuse code, eliminate duplications in a query, or try to do everything with the same query. Here is a very comprehensive article on how to handle this topic:
Dynamic Search Conditions in T-SQL by Erland Sommarskog
It covers all the issues and methods of trying to write queries with multiple optional search conditions. This main thing you need to be concerned with is not the duplication of code, but the use of an index. If your query fails to use an index, it will preform poorly. There are several techniques that can be used, which may or may not allow an index to be used.
here is the table of contents:
Introduction
The Case Study: Searching Orders
The Northgale Database
Dynamic SQL
Introduction
Using sp_executesql
Using the CLR
Using EXEC()
When Caching Is Not Really What You Want
Static SQL
Introduction
x = #x OR #x IS NULL
Using IF statements
Umachandar's Bag of Tricks
Using Temp Tables
x = #x AND #x IS NOT NULL
Handling Complex Conditions
Hybrid Solutions – Using both Static and Dynamic SQL
Using Views
Using Inline Table Functions
Conclusion
Feedback and Acknowledgements
Revision History
if you are on the proper version of SQL Server 2008, there is an additional technique that can be used, see: Dynamic Search Conditions in T-SQL Version for SQL 2008 (SP1 CU5 and later)
If you are on that proper release of SQL Server 2008, you can just add OPTION (RECOMPILE) to the query and the local variable's value at run time is used for the optimizations.
Consider this, OPTION (RECOMPILE) will take this code (where no index can be used with this mess of ORs):
WHERE
(#search1 IS NULL or Column1=#Search1)
AND (#search2 IS NULL or Column2=#Search2)
AND (#search3 IS NULL or Column3=#Search3)
and optimize it at run time to be (provided that only #Search2 was passed in with a value):
WHERE
Column2=#Search2
and an index can be used (if you have one defined on Column2)
if #param = 'whatever'
select * from tbl where id in (1,2,4,5,8)
else
select * from tbl where id in (9,7,3)