Идея в 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";