如何编写EF Core多表筛选查询?ASP Core 2场景需求实现
嘿,我来帮你搞定这个需求!咱们一步步来实现基于ASP.NET Core 2 + EF Core + SQL Server的分销商专属制造商查询功能:
第一步:确认实体模型的关联关系
首先得确保你的实体类之间的关联是正确的,这样EF Core才能正确识别数据关系:
- 你的
ApplicationUser(对应用户表)需要关联分销商:public class ApplicationUser : IdentityUser { public int DistributorId { get; set; } public virtual Distributor Distributor { get; set; } } Distributor类要包含对应的制造商集合:public class Distributor { public int Id { get; set; } // 其他分销商属性... public virtual ICollection<Manufacturer> Manufacturers { get; set; } = new List<Manufacturer>(); }Manufacturer类要标记所属的分销商ID:public class Manufacturer { public int Id { get; set; } // 其他制造商属性... public int DistributorId { get; set; } public virtual Distributor Distributor { get; set; } }
别忘了在DbContext里配置这些实体的DbSet和外键关系哦!
第二步:在控制器中注入必要的服务
在ManufacturersController里,我们需要注入EF Core的上下文和用户管理服务,用来获取当前登录用户的信息:
private readonly ApplicationDbContext _context; private readonly UserManager<ApplicationUser> _userManager; public ManufacturersController(ApplicationDbContext context, UserManager<ApplicationUser> userManager) { _context = context; _userManager = userManager; }
第三步:实现获取当前分销商所有制造商的方法
这个方法的核心是先拿到当前用户关联的分销商ID,再过滤出该分销商下的所有制造商:
[HttpGet] public async Task<IActionResult> GetManufacturers() { // 获取当前登录的用户 var currentUser = await _userManager.GetUserAsync(User); if (currentUser == null) { return Unauthorized("用户未登录或认证失败"); } // 过滤出当前分销商下的所有制造商 var manufacturers = await _context.Manufacturers .Where(m => m.DistributorId == currentUser.DistributorId) .ToListAsync(); return Ok(manufacturers); }
第四步:实现获取当前分销商下指定ID制造商的方法
这里要额外注意:必须同时验证制造商的ID和所属分销商ID,防止用户越权访问不属于自己分销商的制造商:
[HttpGet("{id}")] public async Task<IActionResult> GetManufacturer(int id) { var currentUser = await _userManager.GetUserAsync(User); if (currentUser == null) { return Unauthorized("用户未登录或认证失败"); } // 查找当前分销商下指定ID的制造商 var manufacturer = await _context.Manufacturers .FirstOrDefaultAsync(m => m.Id == id && m.DistributorId == currentUser.DistributorId); if (manufacturer == null) { // 这里可以根据业务需求返回NotFound或Unauthorized,前者更符合REST规范 return NotFound("未找到该制造商,或您无权访问"); } return Ok(manufacturer); }
额外优化小技巧
- 把获取当前用户分销商ID的逻辑抽成私有方法,减少重复代码:
private async Task<int?> GetCurrentUserDistributorId() { var currentUser = await _userManager.GetUserAsync(User); return currentUser?.DistributorId; } - 如果用JWT认证,可以在登录时把
DistributorId加入Token的Claim中,这样不用每次查询用户表,直接从User.Claims里取,提升性能:// 登录时添加Claim示例 var claims = new List<Claim> { new Claim(ClaimTypes.NameIdentifier, user.Id), new Claim("DistributorId", user.DistributorId.ToString()) }; // ...生成JWT Token // 控制器中直接获取 var distributorId = int.Parse(User.FindFirstValue("DistributorId"));
内容的提问来源于stack exchange,提问作者bob
相关产品推荐
相关产品推荐

