Более сложные результаты запроса устанавливают Pk таблицы как нулевые в объектах - PullRequest
3 голосов
/ 30 марта 2019

Я пытаюсь извлечь данные из базы данных mysql, используя dapper, но в результате в качестве значений идентификатора (первичного ключа) и внешнего ключа заданы пустые значения.Другие атрибуты имеют значения.

Я пытался изменить sql-запрос из select * из курсов в полную форму, как select id, name, сделал из курсов.

    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;
       }
   }

Course Schema

Ожидаемый: в списке курсов есть все курсы из db с правильными значениями.

В списке фактических курсов есть все курсы из db с идентификатором и он имеет значение null, а остальные имеют значения.

1 Ответ

2 голосов
/ 30 марта 2019

Даже если бы проблема была решена в комментариях к вопросу Максимом , я бы хотел описать проблему несколькими вариантами решения.

Причина проблемы:

Dapper выполняет сопоставление результата SQL-запроса с объектом по имени . Поле результата запроса Sql 'title' автоматически сопоставляется с Course.Title (отображение не учитывает регистр ).

В вашем случае было два несоответствия имен между столбцами db и свойствами 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 - это функция, позволяющая вручную определить для каждого объекта, какой столбец сопоставлен с каким свойством.

Вот класс, который имеет дело с отображениями (идея для этого двустороннего отображения заимствована из другого ответа SO ):

    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();
...