我正在尝试使用dapper从mysql数据库检索数据,但是结果将id(主键)和外键设置为null。其他属性具有值。
我试图将SQL查询从选择*从课程更改为完整格式,作为选择ID,名称,从课程的ID。
Course{
public Course()
{
}
public string Id { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public bool Is_Elective { get; set; }
public string DId { get; set; }
public int Sem { get; set; }
}
class CourseDAO
{
private readonly MySqlConnection conn;
private string connectionString = "Server=localhost;Database=university;Uid=root;Pwd=*****;";
public CourseDAO()
{
conn = new MySqlConnection(connectionString);
}
public List<Course> getAll()
{
string sql = "select * from university.course";
List<Course> courses = conn.Query<Course>(@sql).ToList();
return courses;
}
}
预期: 课程列表中所有来自db的课程都具有正确的值。
实际 课程列表包含db中所有ID为ID的课程,并且为null,其余则具有值。
答案 0 :(得分:2)
即使Maxim通过问题注释解决了问题,我也想用很少的解决方案来描述问题。
问题原因:
Dapper执行从SQL查询结果到对象按名称的映射。 SQL查询结果字段“标题”会自动映射到Course.Title(映射不区分大小写- )。
在您的情况下,数据库列与C#属性之间存在两个名称不匹配的情况:(course_id
!= Id
和department_id
!= DId
),因此是Dapper无法映射这些字段。
解决方案1,sql列别名
您可以按照以下方式在sql查询中列出具有可能的列别名的表列:
string sql = "select course_id Ad Id, title, credits, Is_elective, department_id as DId, sem from university.course";
在sql中使用显式列名,Dapper可以执行基于名称的自动映射。
解决方案2,Dapper自定义映射
Dapper Custom mapping是为每个对象手动定义哪个列映射到哪个属性的功能。
这里是处理映射的类(从another SO answer借用的双向映射的思想):
public class ColumnMap
{
private readonly Dictionary<string, string> mappings = new Dictionary<string, string>();
public void Add(string t1, string t2)
{
mappings.Add(t1, t2);
}
public string this[string index]
{
get
{
// Check for a custom column map.
if (forward.ContainsKey(index))
return forward[index];
if (reverse.ContainsKey(index))
return reverse[index];
// If no custom mapping exists, return the value passed in.
return index;
}
}
}
设置ColumnMap对象,并告诉Dapper使用该映射。
var columnMap = new ColumnMap();
columnMap.Add("Id", "course_id");
columnMap.Add("DId", "department_id");
SqlMapper.SetTypeMap(typeof (Course), new CustomPropertyTypeMap(typeof (Course), (type, columnName) => type.GetProperty(columnMap[columnName])));
解决方案3,动态类型和LINQ 您可以使用动态对象执行字段映射,如下所示:
string sql = "select * from university.course";
List<Course> courses = conn.Query<dynamic>(@sql)
.Select(item => new Course()
{
Id = item.course_id,
Title = item.title,
Credits = item.credits,
Is_Elective = item.Is_elective,
DId = department_id,
Sem = sem
})
.ToList();