I have a Dapper DB call that has a column that maps to an enum on the type. From what I understand, I have to query using dynamic because the query can't map to my Request
type since Status
is an enum on it. So I tried using this:
public async Task<Request> GetByRequestId(long id)
{
string sql = "SELECT * FROM Request WHERE ID = @id";
using (var connection = new SqlConnection(_connectionString))
{
// Need dynamic here because of the conversion of the Status column as an enum.
// If someone has a better way...
dynamic dynamicRequest = await connection.QueryFirstOrDefaultAsync(sql, new { id });
if (dynamicRequest == null) { return default; }
var request = new Request
{
Id = dynamicRequest.ID,
Status = (RequestStatus)Enum.Parse(typeof(RequestStatus), dynamicRequest.Status)
};
return request;
}
}
However, I can't access any of the properties on the dynamic object, called dynamicRequest
. When debugging, I can see its value like this:
{{DapperRow, ID = '8', FooID = '12', Status = 'N'}}
How can I access ID
, or FooID
, or Status
? This doesn't work:
dynamicRequest.ID
dynamicRequest[0]
dynamicRequest["ID"]
// and many other tries...
This is the error I get if I try using the actual class, instead of dynamic:
System.Data.DataException HResult=0x80131501 Message=Error parsing column 4 (Status=N - String) ArgumentException: Requested value 'N' was not found.
And this is the enum. I just added the JsonConverter
attribute to try and get this to work with the actual Request
class.
[JsonConverter(typeof(StringEnumConverter))]
public enum RequestStatus
{
[EnumMember(Value = "N")]
New = 1,
[EnumMember(Value = "A")]
Approved = 2,
[EnumMember(Value = "C")]
Cancelled = 3,
[EnumMember(Value = "D")]
Declined = 4,
[EnumMember(Value = "P")]
Pending = 5,
}
Here is a screenshot of dynamicRequest
and an attempt at accessing the ID property.
Your problem is the Enum.Parse
doesn't honor your EnumMember
attributes.
This works however.
public static async Task<Request> GetByRequestId(long id)
{
string sql = "SELECT * FROM Request WHERE ID = @id";
using (var connection = new SqlConnection(_connectionString))
{
// Need dynamic here because of the conversion of the Status column as an enum.
// If someone has a better way...
dynamic dynamicRequest = await connection.QueryFirstOrDefaultAsync(sql, new { id });
if (dynamicRequest == null) { return default; }
var request = new Request
{
Id = dynamicRequest.ID,
Status = JsonConvert.DeserializeObject<RequestStatus>($"\"{dynamicRequest.Status}\""),
};
return request;
}
}
Running I get...
Then the mapped Request...
This is what my database table looks like...
User contributions licensed under CC BY-SA 3.0