question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Discussion about replacing CTE with other query using linq2db

See original GitHub issue

This it not really an issue, it’s a continuation of a discussion here

Steps to reproduce

Here is the goal of the query I’m trying to generate and why I was initially using CTE.

When test results are updated for a given equipment, I need to reprocess them with previous results on the same equipment to compute rates of changes between results (also need to check if there are more recent results for the same equipment as their respective rates of change will also be affected by changing the “current” results).

Here is the query I’m using (put in context with the table below)

var queryResult = await _dbContext.TestResults.FromSqlRaw($@"
    WITH equipmentResults AS
    (
        SELECT ROW_NUMBER() OVER (Order BY EquipmentId, TestDate) AS rn
        , *
        FROM dbo.TestResults
        WHERE EquipmentId IN (1,2)                            
    ),
    relatedRowNumbers AS 
    (
        SELECT
        rn AS currentResultRN,
        rn+1 AS nextResultRN
        from equipmentResults
        WHERE Id IN (4,10)
    )
    SELECT * from equipmentResults
    WHERE rn IN (select currentResultRN from relatedRowNumbers) OR rn IN (select nextResultRN from relatedRowNumbers)")
.ToListAsync();

To accomplish this I do the following:

First create a list of all the equipment for which results have been updated since last rate compute task has run. This list is used as a parameter to the 1st CTE, which returns me a list containing all the test results of all the specified equipment (in the example equipment with id 1 and 2).

Once I have this list, I then need to find the specific rows for which results have been updated, and then go on to find their adjacent rows (results are also sorted by date in 1st CTE). This is what the 2nd CTE is used for (attributing row numbers (here the window function could be beneficial I guess)

Here is an example result table after running 1st CTE, in which I identified the rows that I need to retrieve in the final result (and for which I used the 2nd CTE and final SELECT clause). So at the end, EF would need to return rows with rn in (3,4,5,9,10,11) or ResultsRowId in (3,4,5,54,108,109) if not using second CTE

Rn EquipmentId ResultsRowId Date Updated Note
1 1 1 2020-06-05
2 1 2 2020-06-06
3 1 3 2020-06-07 Previous relative to 1st
4 1 4 2020-06-08 1st results row updated
5 1 5 2020-06-09 Next (relative to 1st)
6 2 28 2020-06-10
7 2 29 2020-06-11
8 2 31 2020-06-12
9 2 54 2020-06-13 Previous
10 2 108 2020-06-14 2nd results row updated
11 2 109 2020-06-15 Next
12 2 111 2020-06-16
13 2 112 2020-06-17

Environment details

linq2db version: None yet 😃 Database Server: SQL Server Database Provider: MS SQL Server Operating system: Windows 10 .NET Framework: .net core 3.1

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:50 (27 by maintainers)

github_iconTop GitHub Comments

1reaction
sdanylivcommented, Jun 6, 2020

Yes, good place. I’ll find time to support properties convertors, but it is not simple task.

1reaction
sdanylivcommented, Jun 6, 2020

Oh, yes, we have limitations. Currently we do not support entity property value conversion. But it’s easy to solve. ONCE per application.

MappingSchema.Default.SetConverter<string, SingleTestResultsTemplate>(str => 
   // do Newtonsoft deserialization here
)
Read more comments on GitHub >

github_iconTop Results From Across the Web

linq2db update with CTE on MySql 8
It is a bug. Please create an issue in linq2db GitHub repository. I know that update with CTE is only tested on Sql...
Read more >
Common Table Expression (CTE)
Defining simple CTE. CTE in LINQ To DB implements IQueryable and any IQueryable can be converted to CTE with the extension method AsCte("optional_name")...
Read more >
Difference between CTE and Temp Table and Table Variable
Temp Table, Table variable and CTE are commonly used way for storing temporary data. In this article, you will learn about the main ......
Read more >
Simplify complex queries with Common Table Expressions ...
The syntax for a CTE uses the WITH keyword and a variable name to create a kind of temporary table that you can...
Read more >
Devs who use EF instead of Dapper: Why? : r/dotnet
Sometimes I'll write a SQL view for a complex query or CTE and then use EF to do sorting/filtering/paging against the view.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found