DapperLib / DapperLib/Dapper

Empty vs. non-empty query results leads to a lookup of different constructors

Open
#1,836 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C#
Stars
18.4k
Forks
3.7k
Avg merge
5h 8m
Merged PRs (30d)
1

Description

This issue is best illustrated with a simple example:

  • Create a single-column table Test(Id)
  • Run a query while the table is empty; Dapper needs a constructor that uses byte[] for the Guid
  • Insert a row into the table, and run the same query; Now Dapper needs a constructor that uses a string

The second constructor in the example below is never called. However, the code will not run if you comment it out, because the first conn.Query<UseGuid> throws an exception without it.

You can fix this problem by skipping the constructor lookup when you detect that there is nothing to return.

using System;
using Microsoft.Data.Sqlite;
using System.Data;
using System.Data.Common;
using Dapper;

using var conn = new SqliteConnection("DataSource=database.sqlite");
conn.Open();
conn.Execute("DROP TABLE IF EXISTS Test");
conn.Execute("CREATE TABLE Test (Id BLOB)");
conn.Query<UseGuid>("SELECT Id AS id FROM Test"); // Empty
conn.Execute("INSERT INTO Test (Id) VALUES (@id)", new { id = Guid.NewGuid() });
conn.Query<UseGuid>("SELECT Id AS id FROM Test"); // Non-empty

class UseGuid {
    public UseGuid(string id) {
        Console.WriteLine(id);
    }
    public UseGuid(byte[] id) {
        Console.WriteLine(id.Length);
    }
}

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at Dapper's Query entry point and reproduce the supplied C# example with Microsoft.Data.Sqlite, comparing the empty and populated query paths. The issue is done when an empty result no longer performs constructor lookup while the populated result still maps the Guid value correctly.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, sql, sqlite
Domain
backend, database
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.