如何在ASP.NET WebAPI中通过ADO.NET用SQL查询按用户名获取用户对象
实现方案
这个需求完全可以实现,只需要调整原有方法的返回类型、编写参数化SQL查询,补充实体映射逻辑即可,具体修改如下:
1. 调整方法签名
你当前的方法返回值为Task<bool>,无法承载用户对象,需要修改为返回你定义的用户实体类型(示例中对应EF上下文的Contact类),查询不到用户时返回null:
// 假设你的用户实体类为Contact,可替换为你自己定义的用户类 public async Task<Contact> GetUserById(string username)
2. 编写SQL查询与执行逻辑
使用参数化查询避免SQL注入风险,SQL语句直接查询对应用户的全量字段,同时保持和EF原有逻辑一致的小写匹配规则:
public async Task<Contact> GetUserById(string username) { Contact user = null; string usernameCheck = username.ToLower(); try { OpenConnection(); BeginTransaction(); // 参数化SQL查询,只查匹配的第一条记录即可 string query = "SELECT TOP 1 Id, UserId, Email, /* 这里补全你需要的所有用户字段 */ FROM Contacts WHERE LOWER(UserId) = @Username"; using (SqlCommand command = new SqlCommand(query, connection, transaction)) { // 添加查询参数,避免SQL注入 command.Parameters.AddWithValue("@Username", usernameCheck); // 执行查询读取数据 using (SqlDataReader reader = await command.ExecuteReaderAsync()) { // 匹配到用户则映射到实体对象 if (await reader.ReadAsync()) { user = new Contact() { UserId = reader["UserId"].ToString(), // 依次补全其他字段的映射,比如: // Email = reader["Email"].ToString(), // Id = (int)reader["Id"] }; } } } } catch (Exception ex) { _ = log.WriteLine("ERROR : " + ex.Message + "\nStackTrace : " + ex.StackTrace); } finally { if (user != null) { CommitTransaction(); } else { RollbackTransaction(); } CloseConnection(); } return user; }
注:如果你使用的数据库排序规则本身不区分大小写,可去掉SQL中的
LOWER()函数优化查询性能,只要保证传入的参数和EF逻辑一致做小写转换即可。另外只读查询其实无需开启事务,保留现有逻辑也不会影响功能。
3. 调用方式
完全符合你预期的调用逻辑,拿到返回的用户对象后,直接判断是否为null即可确认用户是否存在,同时可以直接复用该对象做后续操作:
var user = await accountRepository.GetUserById(createUserDto.UserId); if (user != null) { // 用户存在,返回用户名已占用 return BadRequest("Username is taken"); } // 后续可以直接使用user对象做其他操作
内容的提问来源于stack exchange,提问作者NikolaCSI
相关产品推荐
相关产品推荐

