REST的想法是,如果可能有一个未知记录的http请求,我们将返回404(如果存在),然后返回员工的角色。
幼稚的方式是我可以在两个SQL语句中执行此操作,如果未找到,则检查第一个return null的结果,否则继续获取角色。调用者可以检查该函数的结果是否为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";
答案 0 :(得分:1)
我建议像这样使用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位)。