Объект Dapper maps использует второй столбец ID, а не первый

#c# #sql #dapper

#c# #sql #dapper

Вопрос:

Мой SQL-запрос возвращает информацию о сотрудниках, которую я сопоставляю с dapper. SQL возвращает PK из таблицы Employee вместе с различными другими столбцами, а затем PK каждого дочернего объекта с их столбцами. Но первый объект, EmployeeModel, получает PK первого дочернего объекта. Я безуспешно пытался изменить порядок SQL-запроса. Возможно, я неправильно понимаю синтаксис Dapper?

 var sql = @"SELECT e.id, e.FirstName, e.LastName, e.Nickname, 
                                    em.id, em.Address, em.Type, 
                                    jt.id, jt.Name, 
                                    p.id, p.Number, p.Type,
                                    d.id, d.Name,
                                    es.id, es.Name
                                   

                          FROM dbo.Employees e 
                          LEFT JOIN dbo.Emails em
                          ON em.EmployeeID = e.id
                          LEFT JOIN dbo.JobTitles jt                           
                          ON e.JobTitleID = jt.id
                          LEFT JOIN Phones p
                          ON p.EmployeeID = e.id
                          LEFT JOIN dbo.Departments d
                          ON e.DepartmentID = d.id
                          LEFT JOIN dbo.EmployeeStatus es  
                          ON e.StatusID = es.id";

                var employees = await connection.QueryAsync<EmployeeModel,
                                                            EmailModel,
                                                            TitleModel,
                                                            PhoneModel,
                                                            DepartmentModel,
                                                            EmployeeModel>
                                                            (sql, (e, em, t, p, d) =>
                {
                    e.EmailList.Add(em);
                    e.JobTitle = t;
                    e.Department = d;
                    e.PhoneList.Add(p);
                    return e;
                },
                splitOn: "id, id, id, id, id");
 

Вот результат SQL. Например, первая модель EmployeeModel заканчивается с ID = 2 вместо 9 и так далее. (Информация о пользователе вымышлена.)

 9   Abed    Nadir   Abed    2   Abed.Nadir@Greendale.com    Campus  9   Human Resources Manager 4   555-212-1345    Home    2   Sales   1   Active
9   Abed    Nadir   Abed    2   Abed.Nadir@Greendale.com    Campus  9   Human Resources Manager 13  555-224-7894    Work    2   Sales   1   Active
9   Abed    Nadir   Abed    6   Abed.Nadir@Gmail.com    Personal    9   Human Resources Manager 4   555-212-1345    Home    2   Sales   1   Active
9   Abed    Nadir   Abed    6   Abed.Nadir@Gmail.com    Personal    9   Human Resources Manager 13  555-224-7894    Work    2   Sales   1   Active
9   Abed    Nadir   Abed    7   Abed.Nadir@Yahoo.com    Personal    9   Human Resources Manager 4   555-212-1345    Home    2   Sales   1   Active
9   Abed    Nadir   Abed    7   Abed.Nadir@Yahoo.com    Personal    9   Human Resources Manager 13  555-224-7894    Work    2   Sales   1   Active
10  Jeffrey Winger  Winger  1   Jeff.Winger@Greendale.com   Campus  3   Machinist   5   555-212-4567    Home    3   Manufacturing   4   Suspended
10  Jeffrey Winger  Winger  1   Jeff.Winger@Greendale.com   Campus  3   Machinist   6   555-207-5432    Work    3   Manufacturing   4   Suspended
10  Jeffrey Winger  Winger  1   Jeff.Winger@Greendale.com   Campus  3   Machinist   7   555-207-2145    Cell    3   Manufacturing   4   Suspended
10  Jeffrey Winger  Winger  3   JeffWinger@HHH.com  Work    3   Machinist   5   555-212-4567    Home    3   Manufacturing   4   Suspended
10  Jeffrey Winger  Winger  3   JeffWinger@HHH.com  Work    3   Machinist   6   555-207-5432    Work    3   Manufacturing   4   Suspended
10  Jeffrey Winger  Winger  3   JeffWinger@HHH.com  Work    3   Machinist   7   555-207-2145    Cell    3   Manufacturing   4   Suspended
11  Annie   Edison  Annie   4   Annie.Edison@Greendale.com  Campus  3   Machinist   8   555-225-3754    Cell    5   Receiving   1   Active
13  Pierce  Hawthorn    Pierce  5   Pierce.Hawthorn@Greendale.com   Campus  9   Human Resources Manager 10  555-225-3525    Home    6   Finance 5   Sabbatical
14  Shirley Bennett Shirley 1006    Shirley.Bennett@Greendale.com   Campus  8   Accounts Payable Clerk  14  555-555-6792    Home    8   Equipment   4   Suspended
14  Shirley Bennett Shirley 1007    JesusLovesMe@TrueFaith.com  Personal    8   Accounts Payable Clerk  14  555-555-6792    Home    8   Equipment   4   Suspended
15  Troy    Barnes  Troy    1008    Troy.Barnes@Greendale.com   Campus  9   Human Resources Manager 15  555-229-2855    Cell    2   Sales   2   Former
15  Troy    Barnes  Troy    1009    ButterflyInTheSky@Gmail.com Personal    9   Human Resources Manager 15  555-229-2855    Cell    2   Sales   2   Former
 

Комментарии:

1. Ну, у вас есть несколько столбцов с именами id , чего вы ожидаете? Это не средство чтения мыслей. Дайте каждому столбцу уникальное имя. Вы правы, что первому объекту не нужен разделенный столбец

2. Ах. Я ожидал, что он увидит их и обработает последовательно. Но если это не так, как это работает, круто.

3. Если все столбцы идентификаторов имеют одинаковые имена, вам нужно указать их только один раз. И: по умолчанию для параметра splitOn используется «Id», поэтому вам вообще не нужно его указывать.

4. Возможно, я ошибаюсь, но, похоже, два ответа здесь противоречат друг другу. Charlieface говорит, что каждому столбцу нужно уникальное имя, в то время как @Palle Due, похоже, говорит, что они не обязательно должны быть уникальными. Я что-то не так понял?

5. Если вы посмотрите на самый первый тест множественного сопоставления здесь , вы увидите, что есть два столбца идентификаторов и нет параметра splitOn.

Ответ №1:

Попробуйте что-то вроде этого:

 var sql = @"SELECT e.id, e.FirstName, e.LastName, e.Nickname, 
                                em.id as em_id, em.Address as em_Address, em.Type as em_Type, 
                                jt.id as jt_id, jt.Name as jt_Name, 
                                p.id as p_id, p.Number as p_Number, p.Type as p_Type,
                                d.id as d_id, d.Name as d_Name,
                                es.id as es_id, es.Name as es_Name
                               

                      FROM dbo.Employees e 
                      LEFT JOIN dbo.Emails em
                      ON em.EmployeeID = e.id
                      LEFT JOIN dbo.JobTitles jt                           
                      ON e.JobTitleID = jt.id
                      LEFT JOIN Phones p
                      ON p.EmployeeID = e.id
                      LEFT JOIN dbo.Departments d
                      ON e.DepartmentID = d.id
                      LEFT JOIN dbo.EmployeeStatus es  
                      ON e.StatusID = es.id";

            var employees = await connection.QueryAsync<EmployeeModel,
                                                        EmailModel,
                                                        TitleModel,
                                                        PhoneModel,
                                                        DepartmentModel,
                                                        EmployeeModel>
                                                        (sql, (e, em, t, p, d) =>
            {
                e.EmailList.Add(em);
                e.JobTitle = t;
                e.PhoneList.Add(p);
                e.Department = d;
                return e;
            },
            splitOn: "em_id, jt_id, p_id, d_id");
 

Комментарии:

1. Это сработало, за исключением того, что я только поместил модификаторы «as» в столбец id.