I've encountered an issue after I upgraded to the latest version of Dapper from Nuget (v 1.7).
It always return the first enums member (that is, it fail to maps).
I am using MySQL as the database.
CREATE TABLE `users_roles` ( `userId` INT(11) NOT NULL, `roleId` INT(11) NOT NULL, KEY `user_id` (`userId`), KEY `role_id` (`roleId`) ); INSERT INTO `users_roles` (`userId`, `roleId`) VALUES (1, 1); INSERT INTO `users_roles` (`userId`, `roleId`) VALUES (2, 2); public enum Role { Anonymous = 0, Authenticate = 1, Administrator = 2 } var role = Current.Db.Query<Role>(@"SELECT roleId as Role FROM users_roles WHERE userId=@id", new { id = 2 }).FirstOrDefault();
It gives the expected output in Dapper nuget v1.6. Is this the correct behavior for the new version (1.7)?
Update:
After doing some testing with a few console application and fresh mvc3 appications I found that the behavior of Dapper enum mapping is inconsistent when you map the enum type directly.
However, mapping an enum as a property of a class somehow consistently returns the correct map
public class User { public int Id { get; set; } public Role Role { get; set; } } var user = Current.Db.Query<User>(@"SELECT roleId as Role, userId as Id FROM users_roles WHERE userId=@id", new { id = 2 }).FirstOrDefault();
the result of user.Role somehow returns the expected output
Until the bug is fixed my workaround is to modify GetDeserializer method with extra condition
|| type.IsEnum
to use struct deserializer for enums as follows:
private static Func<IDataReader, object> GetDeserializer(Type type, IDataReader reader, int startBound, int length, bool returnNullIfFirstMissing) { ... if (!(typeMap.ContainsKey(type) || type.IsEnum /* workaround! */ || type.FullName == LinqBinary)) { return GetTypeDeserializer(type, reader, startBound, length, returnNullIfFirstMissing); } return GetStructDeserializer(type, startBound); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With