我正在使用dapper从表中查询数据,然后将其强制转换为对象。当将其强制转换为对象时,guid属性设置为全零,但所有其他道具均设置为正确。
public class UserStuff
{
public int Id { get; set; }
public Guid UId { get; set; }
}
public async Task<UserStuff> GetUserStuff(Guid uId){
using(IDbConnection conn = Connection){
string sQuery = "SELECT TOP 100 id, u_id " +
"FROM TestTable WHERE u_id = @u_id ";
conn.Open();
var result = await conn.QueryAsync<UserStuff>(sQuery, new { u_id = uId });
return result.FirstOrDefault();
}
}
示例SQL数据:
id | u_id
5 | C9DB345B-D460-4D71-87E0-D9A3B5CE1177
正在返回: ID为5,GUID为全零
答案 0 :(得分:3)
这里的核心问题是您的列名和属性名不同。因此,即使数据库通过SQL查询返回该值,也不会将其映射到您的属性。由于属性的数据类型为GUID
,因此它保留其默认值-全零。
Dapper映射适用于约定;讨论的话题比较广泛。对于您的特定问题,您的列名称和属性名称应匹配。如果不一致,还有其他方法可以使映射正确发生。
我将在这里提出简单的解决方案:
您可以指示Dapper在映射时忽略列名中的下划线。
using Dapper;
Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
在项目启动时的某个地方设置此属性。
在SQL查询中使用列别名。将您的SQL查询更改为以下内容:
SELECT TOP 100 id, u_id as UId....
这样,无需更改列名和属性名,就可以正确填充属性,因为现在已纠正了映射。
更改列名称以与属性名称匹配,反之亦然。我认为这不切实际。
除上述内容外,dapper还提供了一个自定义映射。
答案 1 :(得分:0)
如果类型和属性相等,则Dapper将列与属性匹配
最简单的方法是调整查询
string sQuery = "SELECT TOP 100 id, u_id as uid " +
"FROM TestTable WHERE u_id = @u_id ";
只是一个提示:
您无需手动打开连接。如果连接状态为closed
,则查询完成或失败后,Dapper会为您执行此操作并关闭它。在更复杂的情况下,这可能是必需的,但在您的情况下则没有必要。
另一个提示: 请勿在SQLServer中对列名使用下划线。按照SqlServer中的约定,我们应该使用大写字母列名称。