【问题标题】:Dapper query result sets Pk of table as null in objectsDapper 查询结果在对象中将表的 Pk 设置为 null
【发布时间】:2019-03-30 17:01:05
【问题描述】:

我正在尝试使用 dapper 从 mysql 数据库中检索数据,但结果集 id(主键)和外键为空值。其他属性也有值。

我尝试将 sql 查询从 select * from course 更改为 select id,name,did from courses 的完整形式。

    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 为 null,rest 有值。

【问题讨论】:

  • 您的班级中的属性名称不正确。将 ID 更改为 course_id,将 DId 更改为 department_id,反之亦然。默认情况下,dapper 尝试按名称应用值(使用忽略大小写策略)。

标签: c# dapper


【解决方案1】:

即使Maxim 在问题 cmets 中解决了问题,我还是想用很少的解决方案来描述问题。

问题原因:

Dapper 执行从 sql 查询结果到 按名称 的对象的映射。 Sql 查询结果字段 'title' 会自动映射到 Course.Title(映射不区分大小写)。

在您的情况下,db 列与 C# 属性之间存在两个名称不匹配:(course_id != Iddepartment_id != DId),因此 Dapper 无法映射这些字段。

方案一,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();

【讨论】:

    猜你喜欢
    • 2019-12-29
    • 1970-01-01
    • 1970-01-01
    • 2020-01-15
    • 2015-01-02
    • 2019-12-29
    • 1970-01-01
    • 1970-01-01
    • 2014-06-03
    相关资源
    最近更新 更多