I created an Inline Table-Valued Functions (ITVF) in SQL Server that returns a table of values (query simplified for discussion purposes):
CREATE FUNCTION dbo.VehicleRepairStatus()
RETURNS TABLE
AS
RETURN
SELECT VehicleID, CurrentStatus
FROM VehicleRepairHistory
...
Which I can reference in a query:
SELECT
v.ID, v.Name,
r.CurrentStatus
FROM
Vehicle v
LEFT OUTER JOIN
dbo.VehicleRepairStatus() r on v.ID = r.VehicleID
I'd like to be able to use it in Linq query:
var vehicles = await _databaseContext.Vehicles
.Join() // join ITVF here?
.Where(v => v.Type == 'Bus' )
.OrderBy(v => v.Name)
.ToAsyncList();
At some point, I may change the ITVF to include a parameter:
CREATE FUNCTION dbo.VehicleRepairStatus(@id AS INT)
RETURNS TABLE
AS
RETURN
SELECT VehicleID, CurrentStatus
FROM VehicleRepairHistory
...
WHERE VehicleID = @id
And call like a scalar:
SELECT v.ID, v.Name
,(SELECT val FROM dbo.VehicleRepairStatus(v.ID)) AS CurrentStatus
FROM Vehicle v
Linq query:
var vehicles = await _databaseContext.Vehicles
.Select( ) // call ITVF here?
.Where(v => v.Type == 'Bus' )
.OrderBy(v => v.Name)
.ToAsyncList();
Is either approach possible?
Yes, it's possible by utilizing the EF Core 2.1 introduced query types. Following are the required steps:
First, create a class to hold the TVF record (update it with the correct data types):
Then register it in your
OnModelCreating
:Then expose it from your db context using a combination of
Query
andFromSql
methods:And that's all.
Now you can use it inside your LINQ queries like any other
IQueryable<T>
returning method, for instance:The "select" inside
FromSql
method makes it composable, so the whole query is translated to SQL and executed server side.Update: Actually this doesn't work when used as correlated subquery like the above example (see Reference to an ITVF raises a "second operation started on this context before a previous operation completed" exception). It could be used only if passing constant/variable parameters like
See the answer to the follow up post from the link for correct implementation for correlated query scenarios.