如何在ReportingConcrete类中访问.cshtml后端的LINQ查询对象
问题需求
需要在ReportingConcrete类中获取messageLogs.cshtml页面里Razor GridView执行搜索后得到的logs查询结果,基于该结果生成Excel报表:
- 当GridView执行过搜索操作时,仅导出搜索结果
- 无搜索操作时,导出全库数据(此功能已实现)
现有代码片段
try { //var logsList = await context.MessageArchive.FindAsync(); var logs = await context.MessageArchive .Include(x => x.Conversation).ToListAsync(); if (!string.IsNullOrEmpty(Request.Form["number"])) //仅输入号码时 { NumberSearched = Convert.ToString(Request.Form["number"]); logs = logs.Where(x => x.PhoneNumber == NumberSearched).ToList(); //筛选对应号码的日志 //logsList = logs.Where(x => x.PhoneNumber == NumberSearched).to; } else if (!string.IsNullOrEmpty(Request.Form["fromDate"])) //输入起始日期时 { fromDate = Convert.ToDateTime(Request.Form["fromDate"]); logs = logs.Where(x => x.MessageDate >= fromDate).ToList(); //筛选起始日期之后的日志 if (!string.IsNullOrEmpty(Request.Form["toDate"])) //同时输入结束日期时 { toDate = Convert.ToDateTime(Request.Form["toDate"]); logs = logs.Where(x => x.MessageDate <= toDate).ToList(); //追加结束日期筛选 } } else if (!string.IsNullOrEmpty(Request.Form["toDate"])) //仅输入结束日期时 { toDate = Convert.ToDateTime(Request.Form["toDate"]); logs = logs.Where(x => x.MessageDate <= toDate).ToList(); //筛选结束日期之前的日志 }
实现方案
1. 提取筛选逻辑到共享方法
把页面中的筛选规则抽离成可复用的方法(比如放到MessageArchiveService这类服务类中),让页面和ReportingConcrete共用同一套逻辑,避免重复代码且保证结果一致。
// 示例:共享服务类中的筛选方法 public class MessageArchiveService { private readonly YourDbContext _context; public MessageArchiveService(YourDbContext context) { _context = context; } public async Task<List<MessageArchive>> GetFilteredLogs(string number, DateTime? fromDate, DateTime? toDate) { var query = _context.MessageArchive.Include(x => x.Conversation); if (!string.IsNullOrEmpty(number)) { query = query.Where(x => x.PhoneNumber == number); } if (fromDate.HasValue) { query = query.Where(x => x.MessageDate >= fromDate.Value); } if (toDate.HasValue) { query = query.Where(x => x.MessageDate <= toDate.Value); } return await query.ToListAsync(); } }
2. 页面中调用共享方法获取结果
在messageLogs.cshtml对应的PageModel中,注入服务并调用筛选方法:
public class MessageLogsModel : PageModel { private readonly MessageArchiveService _archiveService; public List<MessageArchive> Logs { get; set; } public string NumberSearched { get; set; } public DateTime? FromDate { get; set; } public DateTime? ToDate { get; set; } public MessageLogsModel(MessageArchiveService archiveService) { _archiveService = archiveService; } public async Task OnGetAsync() { NumberSearched = Request.Form["number"]; DateTime.TryParse(Request.Form["fromDate"], out var parsedFromDate); DateTime.TryParse(Request.Form["toDate"], out var parsedToDate); FromDate = parsedFromDate == default ? null : parsedFromDate; ToDate = parsedToDate == default ? null : parsedToDate; Logs = await _archiveService.GetFilteredLogs(NumberSearched, FromDate, ToDate); } }
3. 在ReportingConcrete中复用逻辑生成报表
在ReportingConcrete中注入同一个服务,传递筛选参数获取对应结果:
public class ReportingConcrete { private readonly MessageArchiveService _archiveService; public ReportingConcrete(MessageArchiveService archiveService) { _archiveService = archiveService; } public async Task<byte[]> GenerateExcelReport(string number, DateTime? fromDate, DateTime? toDate) { // 获取筛选后的日志数据 var filteredLogs = await _archiveService.GetFilteredLogs(number, fromDate, toDate); // 这里编写Excel生成逻辑(比如使用EPPlus、NPOI等库) // ... return excelFileBytes; } }
4. 页面触发导出时传递筛选参数
在页面添加导出按钮,将当前筛选参数传递给导出接口:
<!-- 导出表单示例 --> <form method="post" asp-page-handler="ExportExcel"> <input type="hidden" name="number" value="@Model.NumberSearched" /> <input type="hidden" name="fromDate" value="@Model.FromDate?.ToString("yyyy-MM-dd")" /> <input type="hidden" name="toDate" value="@Model.ToDate?.ToString("yyyy-MM-dd")" /> <button type="submit">导出Excel</button> </form>
在PageModel中添加导出处理方法:
public async Task<IActionResult> OnPostExportExcelAsync(string number, DateTime? fromDate, DateTime? toDate) { var reportingService = new ReportingConcrete(_archiveService); var excelBytes = await reportingService.GenerateExcelReport(number, fromDate, toDate); return File(excelBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "MessageLogs.xlsx"); }
关键说明
- 优先传递筛选参数而非直接传列表:大数据量场景下,传递参数重新执行查询比传递已加载的列表更节省内存
- 共用筛选逻辑:确保页面展示和导出结果完全一致,避免规则不一致导致的差异
- 增加参数校验:实际使用时需添加日期格式、号码合法性等校验,避免异常
内容的提问来源于stack exchange,提问作者user20034277
相关产品推荐
相关产品推荐

