Skip to content

Multi mapper assumes that splitOn column is never 0-index in IDbDataReader #1015

@bawkee

Description

@bawkee

Hi,

I noticed in Dapper that if the column specified in splitOn argument in its Query method is first in the SELECT statement, Dapper will throw the MultiMapException because it can't find it.

This is because the for loop in below method skips the first column due to i > 0:

From SqlMapper.cs

private static int GetNextSplit(int startIdx, string splitOn, IDataReader reader)
{
	if (splitOn == "*")
	{
		return --startIdx;
	}

	for (var i = startIdx - 1; i > 0; --i)
	{
		if (string.Equals(splitOn, reader.GetName(i), StringComparison.OrdinalIgnoreCase))
		{
			return i;
		}
	}

	throw MultiMapException(reader);
}

Now I haven't ever used dapper in any production so I may be missing something big here but I spent several hours trying to figure out any reason why would this be to no avail.

For example, consider the following tutorial I found on http://dapper-tutorial.net/:
https://dotnetfiddle.net/DPiy2b

It works because it has SELECT *, but if you change that SELECT statement to:

SELECT A.OrderID, CustomerID, EmployeeID, OrderDate, ShipperID, ProductID, Quantity

Dapper will throw the aforementioned exception.

Changing the SQL to:

SELECT A.OrderID, A.OrderID, CustomerID, EmployeeID, OrderDate, ShipperID, ProductID, Quantity

Avoids the exception, because Dapper will pick up OrderID when mapping since it starts from 1.

Again this may very well be by design, I can't tell straight away as I've only used dapper for couple of hours since 2015. If it is and I missed something obvious, I apologise for wasting everyone's time!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions