如果Employee存在,则使用ADO.net返回员工角色

时间:2019-10-12 11:05:55

标签: c# .net-core ado.net

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";

1 个答案:

答案 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将是NULLIsDBNull将返回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位)。