5

I am using Dapper to map objects coming out of a SQL Server database to C# classes. One of the stored procedures I need to pull results from can have a variable number of columns depending on the context. This result set will always have a primary key column, and then 0 to 30 additional columns that will all be of the same data type.

The result set columns are basically like this:

CustomerID | Email1 | Email2 | Email3 | ...

Where the number of Email* columns depends on the highest number of email addresses on file for a customer in the query.

The natural way to capture this in C# is with a class like this:

class Customer {
    int ID { get; set; }
    string[] EmailAddresses { get; set; }
}

Is there a way to use Dapper to map my result set to an object like this?

1 Answer 1

6

It is possible if you do a bit of magic via dynamic.

var user = connection.Query("spGetUser", commandType: CommandType.StoredProcedure)
        .Select(x =>
        {
            var result = new Customer { ID = x.Id };
            foreach (var element in x)
            {
                if (element.Key.Contains("Email"))
                    result.EmailAddresses.Add(element.Value.ToString());
            }
            return result;
        }).FirstOrDefault();

public class Customer
{
    public int ID { get; set; }
    public List<string> EmailAddresses { get; set; } = new List<string>();
}

A few key points:

  • The array is changed to a list so that we can easily and dynamically add data to it.
  • Dynamic will always have a small performance hit in comparison to deserializing directly to a strong type.
  • This does not check the type of the data held in the Value property, nor does it check that there is actually a value present before calling .ToString() on it.
Sign up to request clarification or add additional context in comments.

7 Comments

Thank you. I don't think the dynamic and List caveats will cause any issues in my scenario. I will try this at work tomorrow.
The List will be perfectly performant in comparison to an array. The hit from dynamic is small but at least worth noting.
I think the time saved not manually manipulating DataTables will more than make up for it.
Absolutely :). it's a wonderful tool. The flexibility and power is astounding.
Well, in that case, welcome to the other side :). It's a fantastic place to live.
|

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.