Если сотрудник существует, верните роли сотрудников с помощью ADO.net - PullRequest
1 голос
/ 12 октября 2019

Идея в REST заключается в том, что если http-запрос может прийти для неизвестной записи, мы возвращаем 404, если она существует, то роли сотрудника.

Наивным способом было бы сделать это вдва оператора SQL, проверьте результат первого возвращаемого значения null, если не найдено, иначе продолжите поиск ролей. Вызывающий может проверить, является ли результат функции нулевым, и может вернуть 404, основываясь на том, что в противном случае он будет отображать роли пользователя.

"SELECT Id FROM Employee WHERE Id = @Id"
"SELECT * FROM Role WHERE EmployeeId = @Id"

Моя текущая реализация:

public List<object> GetUserRolesById(int id)
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();

        // statement 1
        string sql = "SELECT Id FROM Employee WHERE Id = @Id";
        using (SqlCommand command = new SqlCommand(sql, connection))
        {
            command.Parameters.Add("@Id", SqlDbType.Int, 32).Value = id;
            using (SqlDataReader reader = command.ExecuteReader())
            {
                if (!reader.Read() || reader.IsDBNull(reader.GetOrdinal("Id")))
                {
                    return null; // caller to return 404 if record not found
                }
            }
        }

        // statement 2
        sql = @"SELECT Id, Name FROM Role WHERE EmployeeId = @Id";
        using (SqlCommand command = new SqlCommand(sql, connection))
        {
            command.Parameters.Add("@Id", SqlDbType.Int, 32).Value = id;
            using (SqlDataReader reader = command.ExecuteReader())
            {
                List<object> roles = new List<object>();
                if (reader.Read())
                {
                    for (int i = 0; i < roleIds.Length; i++)
                    {
                        roles.Add(new {Id = Int32.Parse(reader.GetString((0)), Name = reader.GetString(1)});
                    }
                }
                return roles;
            }
        }
    }        
}

Вопрос:

Как лучше объединить оба оператора SQL в одном?

Изменить

После ответа, включив предложения в мое решение, минус пользовательское несуществующее условие.

using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();
    string sql = @"
        SELECT Employee.Id, Role.Id AS [RoleId], Role.NAME AS [RoleName]
        FROM Employee
        LEFT OUTER JOIN EmployeeRole on Employee.Id = EmployeeRole.EmployeeId
        LEFT OUTER JOIN Role on EmployeeRole.RoleId = Role.Id
        WHERE Employee.Id = @Id";

    using (SqlCommand command = new SqlCommand(sql, connection))
    {
        command.Parameters.Add("@Id", SqlDbType.Int).Value = id;
        using (SqlDataReader reader = command.ExecuteReader())
        {
            List<object> roles = new List<object>();
            while (reader.Read()) // 404 condition missing?
            {
                roles.Add(new {Id = reader.GetInt32(1), Name = reader.GetString(2)});
            }
            return roles;
        }
    }
}

Запрос 2

Будет ли это работать, если мы объединим оба запроса? Тем не менее, я не знаю, как получить двойной результат запроса от читателя.

string sql = @"SELECT FIRST FROM Employee WHERE Id = @Id;
    SELECT Employee.Id, Employee.First, Role.Id AS [RoleId], Role.NAME AS [RoleName]
    FROM Employee
    LEFT OUTER JOIN EmployeeRole on Employee.Id = EmployeeRole.EmployeeId
    LEFT OUTER JOIN Role on EmployeeRole.RoleId = Role.Id
    WHERE Employee.Id = @Id2";

1 Ответ

1 голос
/ 12 октября 2019

Я бы предложил использовать SQL, например:

SELECT Employee.Id, Role.WhateverColumnYouWantHere
FROM Employee LEFT OUTER JOIN Role On Employee.Id = Role.EmployeeID
WHERE Employee.Id = @Id

Если сотрудника нет, Read вернет false. Если сотрудник присутствует, но ему не хватает роли, то Role.WhateverColumnYouWantHere будет NULL (IsDBNull вернет true).

Кроме того, вы, вероятно, захотите удалить свой for (int i = 0; i < roleIds.Length; i++) цикл (оставьте логику внутри него - просто удалите цикл), поскольку он не делает ничего полезного. Кроме того, измените if (reader.Read()) на while (reader.Read()) для обработки возможности нескольких ролей. Кроме того, вам, вероятно, следует использовать reader.GetInt32(0) вместо Int32.Parse(reader.GetString((0)) - при условии, что Id является 32-разрядным целым числом (а не строкой). Также удалите код , 32 - это не нужно, поскольку SqlDbType.Int имеет фиксированный размер (т. Е. Он знает, что он 32-битный).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...