From 9f1cda3ec1455ecff30aa10b6530180d75ded870 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 15 Mar 2026 01:30:22 +0000 Subject: [PATCH 1/2] fix: resolve FSharp.Core version mismatch in item type resolution (Closes #433) When the F# compiler process runs at a different FSharp.Core version than the compiled project (e.g. compiler has 8.0.0.0, project is pinned to 7.0.0.0), the assembly-qualified type name baked into the quoted expression by the design time DLL contains the compiler's FSharp.Core version. At runtime, Type.GetType then fails with FileLoadException because the requested assembly version is not loaded. Fix: try the exact assembly-qualified name first; if that returns null, strip Version/Culture/PublicKeyToken from all assembly references in the name and retry, allowing the runtime's own assembly-binding logic to locate the correct version of FSharp.Core (or any other assembly affected by the same pattern). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/SqlClient/ISqlCommand.fs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/SqlClient/ISqlCommand.fs b/src/SqlClient/ISqlCommand.fs index ec6b76a7..2cdfeb96 100644 --- a/src/SqlClient/ISqlCommand.fs +++ b/src/SqlClient/ISqlCommand.fs @@ -21,6 +21,7 @@ open System open System.Data open System.Data.SqlClient open System.Reflection +open System.Text.RegularExpressions open FSharp.Data.SqlClient open FSharp.Data.SqlClient.Internals open System.Linq @@ -33,6 +34,23 @@ module Seq = | [| x |] -> Some x | _ -> invalidArg "source" "The input sequence contains more than one element." +module internal TypeResolution = + + // Resolves a type by its assembly-qualified name, with a version-tolerant fallback. + // The design-time DLL runs inside the F# compiler process and bakes the compiler's FSharp.Core + // version into item type names. If the user's project references a different FSharp.Core version, + // Type.GetType with the exact name fails with FileLoadException. Stripping version/culture/token + // from the assembly reference lets the runtime's binding logic find the correct assembly. + // See: https://github.com/fsprojects/FSharp.Data.SqlClient/issues/433 + let resolveType (typeName: string) = + match Type.GetType(typeName, throwOnError = false) with + | null -> + let stripped = Regex.Replace(typeName, @",\s*Version=[^,\[\]]+", "") + let stripped = Regex.Replace(stripped, @",\s*Culture=[^,\[\]]+", "") + let stripped = Regex.Replace(stripped, @",\s*PublicKeyToken=[^,\[\]]+", "") + Type.GetType(stripped, throwOnError = true) + | t -> t + [] type RowMapping = obj[] -> obj @@ -108,7 +126,7 @@ type ``ISqlCommand Implementation``(cfg: DesignTimeConfig, connection: Connectio notImplemented | rowMapping, itemTypeName -> assert ((not(isNull rowMapping)) && (not (isNull itemTypeName))) - let itemType = Type.GetType( itemTypeName, throwOnError = true) + let itemType = TypeResolution.resolveType itemTypeName let executeHandle = typeof<``ISqlCommand Implementation``> From 33ed1eaa9327a8fd19418c21a8e22cc713fc16bf Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 15 Mar 2026 01:37:48 +0000 Subject: [PATCH 2/2] ci: trigger checks