Skip to content

Option not inferred for optional sproc parameters of type binary and nvarchar #377

Open

Description

@cmeeren

Description

SqlClient does not infer the correct optionality for all stored procedure parameters.

For example, given this sproc with three optional parameters

CREATE PROCEDURE [dbo].[Procedure1]
  @param1 int = NULL,
  @param2 nvarchar(10) = NULL,
  @param3 binary(10) = NULL
AS
  SELECT 1

only the first one is inferred to be optional:

image

Note however that the type signature seems correct:

image

Activity

  1. smoothdeveloper commented on Mar 30, 2020

    @smoothdeveloper
    Collaborator

    @cmeeren this is tied to this:

    let valueTypeWithNullDefault = typeInfo.IsValueType && defaultValue = Some(null)

    Only value type are option wrapped, which I think makes sense.

    You may pass null to work around your issue.

  2. cmeeren commented on Mar 30, 2020

    @cmeeren
    ContributorAuthor

    I see, I didn't notice that. Then at least I can use my sprocs :)

    IMHO a uniform option interface for all optional params would make more sense, to clearly indicate that they are, in fact, optional - and also because in F#, we're usually using option for these arguments anyway, so this would save having to use Option.toObj. Feel free to close this issue if you don't agree. :)

  3. github-actions commented on Mar 10, 2026

    @github-actions
    Contributor

    🤖 This is an automated response from Repo Assist.

    Thanks for the detailed report. The root cause is in SqlClientExtensions.fs line 375:

    let valueTypeWithNullDefault = typeInfo.IsValueType && defaultValue = Some(null)
    // ...
    Optional = valueTypeWithNullDefault

    Only parameters whose CLR type is a value type (int, float, DateTime, etc.) get wrapped as T option when they have a NULL default. Reference types like string (nvarchar) and byte[] (binary/varbinary) are excluded because null is already a valid F# value for those types — so you can pass null today as the workaround.

    Making this consistent (wrapping all nullable-defaulted params as option) would be a breaking API change: existing code passing null for string/byte[] parameters would need to be updated to None. Because of this, a fix would need to be opt-in (e.g., a UniformOptionalParameters static parameter on the type provider) or version-gated.

    The immediate workaround is indeed to pass null for nvarchar/binary optional parameters, as @smoothdeveloper noted. For example:

    myCommand.Execute(param1 = Some 42, param2 = null, param3 = null)

    Generated by Repo Assist · ◷

    To install this agentic workflow, run

    gh aw add githubnext/agentics/workflows/repo-assist.md@346204513ecfa08b81566450d7d599556807389f
    

    Warning

    ⚠️ Firewall blocked 1 domain

    The following domain was blocked by the firewall during workflow execution:

    • fsprojects.github.io

    To allow these domains, add them to the network.allowed list in your workflow frontmatter:

    network:
      allowed:
        - defaults
        - "fsprojects.github.io"

    See Network Configuration for more information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions