-1

I am refactoring some code that used reflection to map a SqlCommand to a model. The new code uses the Dapper framework and works perfectly fine:

    Public Shared Function GetModel(Of T As New)(cmd As SqlCommand) As T
        Try

            Dim params = GetParametersDictionary(cmd)
            Dim result As Object

            Using conn As New SqlConnection(ConnectionString)
                result = conn.Query(Of T)(cmd.CommandText, params).FirstOrDefault()
            End Using

            Return result

        Catch ex As Exception
            ErrorsLogger.LogException(ex)
            Throw
        End Try
    End Function

However in the old code I had an edge case for string properties and DbNull values. Something like:

    If IsTypeOfString(prop) AndAlso IsDbNull(value) Then
        prop.SetValue(obj, "")
    End If

The new code does not convert DbNull (NULL) values to an empty string. Instead it leaves the value just not set aka Nothing, breaking some code elsewhere.

So my question is how to change this function to convert NULL values to an empty string? Preferably without reflection.

Things tried / considered / constraints:

  • Custom Dapper SqlMapper: Does not work when values are NULL.
  • Custom model mapper: Cannot create a custom model mapper for every model type.
  • Init strings as "" in class constructor: Cannot guaranty that every string property is correctly initialized with "".
  • Cannot change the queries or model classes (at least for now).
4
  • How about, in the select clause of the SQL using Coalesce(column, '') as column and not deal with this generically at all. (IMHO it is odd to have a model with non-nullable properties when there are nulls in the DB.) Commented Oct 4, 2023 at 12:23
  • Totally agreed. Unfortunately I have to deal with this old code and have no access to the models, or the queries. Updated the question to add this constraint. Commented Oct 4, 2023 at 12:27
  • I never worked with dapper, but you could probably create a type handler for strings. Here is an example of a type handler not doing quite what you need, but you could adapt it: Converting varchar to IHtmlString. Commented Oct 4, 2023 at 12:58
  • @OlivierJacot-Descombes Unfortunately due to how dapper works the CustomTypeHandler (aka Dapper SqlMapper) is not called for NULL values. Commented Oct 4, 2023 at 13:43

1 Answer 1

2

Dapper is of the opinion that null and "" are different things, and actively tries not to conflate the two. You could post-process the results, perhaps.

Sign up to request clarification or add additional context in comments.

4 Comments

Ok. It is going to be Post-processing... For now at least. I am gonna log/find the code that depends on this empty-string-code, and fix it there.
@Vincent you could also just have public string Whatever {get;set;} = ""; so that it is an empty string by default?
NB - I initially voted this up, but after reading the question more thoroughly to understand what it was asking, this does not appear to answer the question, which is a "how to", not a "why" question. Yet, this answer provides a "why" response, with only saying "you could post process" the results for addressing the "how to" part--that's not really a "how to" answer so much as merely a hint at "how to". IMO a good answer would actually show how to post-process the results.
Of course, the fault lies partially also with OP for choosing to mark this as the accepted answer, for some reason, when it does not actually answer the question they posed...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.