c# - Dapper 映射问题
问题描述
我无法让 Dapper 将本地 sqlite Db 中的 sql 结果映射到我们的实体类型对象。
它一直试图将第 n-1 列映射到第 n 列,这会导致它在映射到 DateTime 时死掉(因为前一列不会转换)
异常消息:解析第 2 列时出错(user_pswd_exp_dt=Y - 字符串)
这是一个简化版本,它为我重现了这个问题。
public class UsrMiniDto : IDto
{
[Column( "user_id" )]
public Int64 UserId { get; set; }
[Column( "user_active" )]
public string UserActive { get; set; }
[Column( "user_pswd_exp_dt" )]
public DateTime? UserPswdExpDt { get; set; }
[Column( "add_user" )]
public string AddUser { get; set; }
[Column( "add_dt" )]
public DateTime AddDt { get; set; }
}
public List<UsrMiniDto> GetMiniUsrByUsrName( string usrName )
{
StringBuilder sql = new StringBuilder();
sql.Append( "SELECT u.user_id ," );
sql.Append( "u.user_active ," );
sql.Append( "u.user_pswd_exp_dt " );//as UserPswdExpDt
//sql.Append( ", u.add_user ," );
//sql.Append( "u.add_dt " );
sql.Append( " FROM " );
sql.Append( " usr u" );
sql.Append( " WHERE u.user_login_name = :usrName" );
List<UserInput> listUserInput = new List<UserInput>();
listUserInput.Add( new UserInput( ":usrName", "System.String", usrName ) );
ICustomFixSql customFixSql = ObjectFactory.GetInstance<ICustomFixSql>();
string mainSql = customFixSql.BuildSqlFromUserArgs(sql.ToString(), listUserInput);
try
{
DapperCustomMapping<UsrMiniDto>();
return SqliteGetList<UsrMiniDto>( mainSql );
}
catch ( Exception ex )
{
throw;
}
}
public virtual List<T> SqliteGetList<T>(string mainSql)
{
List<T> x;
using ( SQLiteConnection connection = GetSqLiteConnection() )
{
//dapper
x = connection.Query<T>( mainSql ).ToList();
}
return x;
}
protected void DapperCustomMapping<T>()
{
// custom mapping
var map = new CustomPropertyTypeMap(typeof(T),
(type, columnName) => type.GetProperties().FirstOrDefault(prop => GetDescriptionFromAttribute(prop) == columnName));
SqlMapper.SetTypeMap( typeof( T ), map );
}
private string GetDescriptionFromAttribute( System.Reflection.MemberInfo member )// this lets you override bad mappings via teh column attribute - EWB
{
if ( member == null ) return null;
var attrib = (ColumnAttribute)Attribute.GetCustomAttribute(member, typeof(ColumnAttribute), false);
return attrib == null ? null : attrib.Name;
}
最初我是默认映射,一旦我打开使用下划线映射的设置就遇到了这个问题(以前根本没有映射)
我尝试重命名列以匹配 Sql 中的 DTo 名称。没有喜悦,那么正如您在上面看到的,我尝试使用 column 属性来指定确切的列,但它仍然错过了将列映射为一个。
这是我的代码生成并在查询方法中传递给 Dapper 的 Sql。
SELECT u.user_id ,u.user_active ,u.user_pswd_exp_dt FROM usr u WHERE u.user_login_name = 'KainJesi'
这是返回的行。user_id user_active user_pswd_exp_dt
66657 Y 1/1/2099 12:00:00 AM
如您所见,user_active 错误地尝试映射到 UserPswdExpDt。
我是 Dapper 的菜鸟,我真的下载了它并在星期六开始使用它。
我究竟做错了什么?
我在 .Net 4.5.2 中,所以我不能使用 Dapper.Dimplecrud,我们的其他团队似乎就是这样解决这个问题的。
- - - -更新
根据评论,我将其转换为 Linq2sql 中的 ExecuteQuery,因此
public List<UsrMiniDto> GetMiniUsrByUsrName( string usrName )
{
StringBuilder sql = new StringBuilder();
sql.Append( "SELECT u.user_id as UserId," );
sql.Append( "u.user_active as UserActive," );
sql.Append( "u.user_pswd_exp_dt as UserPswdExpDt " );//as UserPswdExpDt
//sql.Append( ", u.add_user as AddUser," );
//sql.Append( "u.add_dt as AddDt " );
sql.Append( " FROM " );
sql.Append( " usr u" );
sql.Append( " WHERE u.user_login_name = :usrName" );
List<UserInput> listUserInput = new List<UserInput>();
listUserInput.Add( new UserInput( ":usrName", "System.String", usrName ) );
ICustomFixSql customFixSql = ObjectFactory.GetInstance<ICustomFixSql>();
string mainSql = customFixSql.BuildSqlFromUserArgs(sql.ToString(), listUserInput);
try
{
//DapperCustomMapping<UsrMiniDto>();
//return SqliteGetList<UsrMiniDto>( mainSql );
return SqliteGetList2<UsrMiniDto>( mainSql );
}
catch ( Exception ex )
{
throw;
}
}
public virtual List<T> SqliteGetList2<T>( string mainSql )
{
// show complete SQL in log...JK
INetLog log = ObjectFactory.GetInstance<INetLog>();
log.Debug( "SqliteGetList<T>(string mainSql = '" + mainSql + "')" );
List<T> x;
using ( SQLiteConnection connection = GetSqLiteConnection() )
{
//dapper
//x = connection.Query<T>( mainSql ).ToList();
//linq 2 sql
DataContext dc = new DataContext(connection);
x = dc.ExecuteQuery<T>(mainSql).ToList();
}
return x;
}
我得到异常“字符串未被识别为有效的日期时间。”
这听起来像相同的“Y”被映射到 dateTime 问题。但我仍然不知道为什么将列 n-1 映射到 n.. 非常感谢任何帮助。
注意:这似乎是一个特定于 sqlite 的问题,如果我交换连接以指向我们的一个开发数据库,它工作正常。如果我将它指向我的本地 sqlitedb,它会再次崩溃。
解决方案
推荐阅读
- java - 如何获得两个值的和、差、商、乘积并在 textview 中打印出来
- android - JSONArray 保持为空,直到单击菜单项
- python - 在 Geodjango 中通过几何相交关联两个模型
- angular - 我正在使用 *ngFor 来迭代卡片布局中的元素。我想随机改变他们的背景颜色有什么办法吗?
- mysql - 查询以从一个表中生成不同设备的故障日志,在该表中设备输入其状态并带有时间戳
- python - Heroku 应用程序产生一个应用程序错误(“关键工作者超时”),而 celery 后台任务产生一个成功的结果,我做错了什么?
- swift - 打开和保存在非常简单的 Swift 4 基于文档的应用程序中不起作用
- php - 在 PHP 中使用不同参数多次调用函数的更短语法
- ruby - HTTP::persistent 和代理?
- c# - do-while 循环是如何编译的?