Skip to content

Commit 62cbcc0

Browse files
committed
Implemented #850
1 parent 93ed462 commit 62cbcc0

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

src/SQLProvider.Common/SqlRuntime.Common.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1240,5 +1240,5 @@ module public OfflineTools =
12401240
member _.SubmitPendingChangesAsync(): Threading.Tasks.Task<unit> = task {return ()}
12411241
member _.ConnectionString = ""
12421242
member _.IsReadOnly = false
1243-
}
1243+
}
12441244
x :> obj |> unbox<'T>

src/SQLProvider.Common/SqlRuntime.Linq.fs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,7 @@ module internal QueryImplementation =
848848
ForeignTable = {Schema="";Name="";Type=""};
849849
OuterJoin = isOuter; RelDirection = RelationshipDirection.Parents }
850850
SelectMany(sourceAlias,destAlias,LinkQuery(data),outExp)
851-
| OptionalOuterJoin(outerJoin,MethodCall(Some(_),(MethodWithName "CreateRelated"), [param; _; String PE; String PK; String FE; String FK; RelDirection dir;])) ->
851+
| OptionalOuterJoin(outerJoin,MethodCall(Some(_),(MethodWithName "CreateRelated"), [param; _; String pe; String pk; String fe; String fk; RelDirection dir;])) ->
852852

853853
let parseKey itm =
854854
SqlColumnType.KeyColumn itm
@@ -857,7 +857,7 @@ module internal QueryImplementation =
857857
| ParamName x -> x
858858
| PropertyGet(_,p) -> Utilities.resolveTuplePropertyName p.Name source.TupleIndex
859859
| _ -> failwith "unsupported parameter expression in CreatedRelated method call"
860-
let data = { PrimaryKey = [parseKey PK]; PrimaryTable = Table.FromFullName PE; ForeignKey = [parseKey FK]; ForeignTable = Table.FromFullName FE; OuterJoin = outerJoin; RelDirection = dir }
860+
let data = { PrimaryKey = [parseKey pk]; PrimaryTable = Table.FromFullName pe; ForeignKey = [parseKey fk]; ForeignTable = Table.FromFullName fe; OuterJoin = outerJoin; RelDirection = dir }
861861
let sqlExpression =
862862
match outExp with
863863
| BaseTable(alias,entity) when alias = "" ->
@@ -1350,3 +1350,45 @@ module Seq =
13501350
let stdDevQuery<'T when 'T : comparison> : System.Linq.IQueryable<'T> -> 'T = QueryImplementation.getAgg "StdDev"
13511351
/// Execute SQLProvider query to get the variance of elements.
13521352
let varianceQuery<'T when 'T : comparison> : System.Linq.IQueryable<'T> -> 'T = QueryImplementation.getAgg "Variance"
1353+
1354+
/// Query debugging and inspection utilities
1355+
module QueryInspection =
1356+
1357+
/// Generates the SQL query string and parameters without executing the query.
1358+
/// Note: This function creates a database connection to access schema metadata for SQL generation,
1359+
/// but does not execute any queries against the database.
1360+
/// This is useful for debugging, logging, or when you need to execute the query through ADO.NET directly.
1361+
/// Returns a tuple of (SQL query string, array of parameter name-value pairs).
1362+
let toQueryString (query:System.Linq.IQueryable<'T>) : string * (string * obj) array =
1363+
match QueryImplementation.findSqlService query with
1364+
| Some svc, _ ->
1365+
use con = svc.Provider.CreateConnection(svc.DataContext.ConnectionString)
1366+
let (sql, parameters, _, _) =
1367+
QueryExpression.QueryExpressionTransformer.convertExpression
1368+
svc.SqlExpression
1369+
svc.TupleIndex
1370+
con
1371+
svc.Provider
1372+
false
1373+
(svc.DataContext.SqlOperationsInSelect = SelectOperations.DatabaseSide)
1374+
let paramArray =
1375+
parameters
1376+
|> Seq.map (fun p -> p.ParameterName, p.Value)
1377+
|> Seq.toArray
1378+
(sql, paramArray)
1379+
| None, _ ->
1380+
failwithf "The provided query is not a SQLProvider IQueryable. Type: %s" (query.GetType().FullName)
1381+
1382+
/// Extension methods for IQueryable to provide EF Core-like query inspection capabilities
1383+
[<AutoOpen>]
1384+
module IQueryableExtensions =
1385+
1386+
type System.Linq.IQueryable<'T> with
1387+
/// Generates the SQL query string and parameters without executing the query.
1388+
/// Note: This method creates a database connection to access schema metadata for SQL generation,
1389+
/// but does not execute any queries against the database.
1390+
/// This is useful for debugging, logging, or when you need to execute the query through ADO.NET directly.
1391+
/// Returns a tuple of (SQL query string, array of parameter name-value pairs).
1392+
member this.ToQueryString() : string * (string * obj) array =
1393+
toQueryString this
1394+

0 commit comments

Comments
 (0)