如果员工存在,则 return 个员工角色使用 ADO.net
If Employee exists then return employee roles using ADO.net
REST 下的想法是,如果一个 http 请求可能来自未知记录,我们 return 404,如果它存在,那么员工的角色。
天真的方法是,我可以在两个 SQL 语句中执行此操作,检查第一个 return 的结果,如果没有找到则为空,否则继续检索角色。调用者可以检查函数的结果是否为空,并且可以 return 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
如果我们将这两个查询结合起来,它会起作用吗?但是,我不知道如何从 reader.
检索双重查询结果
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";
我建议使用 SQL 如:
SELECT Employee.Id, Role.WhateverColumnYouWantHere
FROM Employee LEFT OUTER JOIN Role On Employee.Id = Role.EmployeeID
WHERE Employee.Id = @Id
如果员工不在,那么 Read
将 return false
。如果员工在那里,但缺少角色,则 Role.WhateverColumnYouWantHere
将是 NULL
(IsDBNull
将 return 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 位)。
REST 下的想法是,如果一个 http 请求可能来自未知记录,我们 return 404,如果它存在,那么员工的角色。
天真的方法是,我可以在两个 SQL 语句中执行此操作,检查第一个 return 的结果,如果没有找到则为空,否则继续检索角色。调用者可以检查函数的结果是否为空,并且可以 return 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
如果我们将这两个查询结合起来,它会起作用吗?但是,我不知道如何从 reader.
检索双重查询结果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";
我建议使用 SQL 如:
SELECT Employee.Id, Role.WhateverColumnYouWantHere
FROM Employee LEFT OUTER JOIN Role On Employee.Id = Role.EmployeeID
WHERE Employee.Id = @Id
如果员工不在,那么 Read
将 return false
。如果员工在那里,但缺少角色,则 Role.WhateverColumnYouWantHere
将是 NULL
(IsDBNull
将 return 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 位)。