ASP.NET Core 5 MVC如何返回非数据库模型列表至Index视图
实现步骤
因为你的数据来自非数据库来源,核心逻辑是先拿到三个原始模型的内存集合,再按业务关联规则映射为目标ViewModel列表,最后传给视图即可。
控制器代码示例
首先修正你现有ViewModel的问题:当前ExampleViewModel里存在两个同名的Attr3属性,会直接编译报错,需要先将重名属性改名区分,比如改为Ex1_Attr3、Ex2_Attr3。
之后在控制器的Index Action中按如下逻辑编写:
public IActionResult Index() { // 1. 获取非数据库来源的原始数据,以下方法替换为你实际的数据源读取逻辑即可,支持从第三方API、本地文件、内存计算、缓存等任意来源读取 List<Example1> ex1Data = GetExample1Source(); List<Example2> ex2Data = GetExample2Source(); List<Example3> ex3Data = GetExample3Source(); // 2. 按业务规则关联组装ViewModel列表,以下是按Example1外键关联的示例,可根据你实际的关联逻辑调整 List<ExampleViewModel> vmList = ( from e1 in ex1Data join e2 in ex2Data on e1.ID_Ex1 equals e2.example1?.ID_Ex1 into e2Matches from matchedE2 in e2Matches.DefaultIfEmpty() join e3 in ex3Data on e1.ID_Ex1 equals e3.example1?.ID_Ex1 into e3Matches from matchedE3 in e3Matches.DefaultIfEmpty() select new ExampleViewModel { ID_Ex1 = e1.ID_Ex1, Attr1 = e1.Attr1, Attr2 = e1.Attr2, Ex1_Attr3 = e1.Attr3, ID_Ex2 = matchedE2?.ID_Ex2 ?? 0, Ex2_Attr3 = matchedE2?.Attr3 ?? 0, Attr4 = matchedE2?.Attr4 ?? 0, Attr5 = matchedE2?.Attr5 ?? 0, ID_Ex3 = matchedE3?.ID_Ex3 ?? 0, Attr6 = matchedE3?.Attr6 ?? 0, Attr7 = matchedE3?.Attr7 ?? 0, Attr8 = matchedE3?.Attr8 ?? 0 } ).ToList(); // 3. 传递强类型列表到视图 return View(vmList); } // 非数据库数据源示例,替换为你实际的读取逻辑即可 private List<Example1> GetExample1Source() { return new List<Example1> { new() { ID_Ex1 = 1, Attr1 = 10, Attr2 = 20, Attr3 = 30 }, new() { ID_Ex1 = 2, Attr1 = 11, Attr2 = 21, Attr3 = 31 } }; } private List<Example2> GetExample2Source() { return new List<Example2> { new() { ID_Ex2 = 101, Attr3 = 301, Attr4 = 401, Attr5 = 501, example1 = new Example1{ ID_Ex1 = 1 } } }; } private List<Example3> GetExample3Source() { return new List<Example3> { new() { ID_Ex3 = 201, Attr6 = 601, Attr7 = 701, Attr8 = 801, example1 = new Example1{ ID_Ex1 = 1 } }, new() { ID_Ex3 = 202, Attr6 = 602, Attr7 = 702, Attr8 = 802, example1 = new Example1{ ID_Ex1 = 2 } } }; }
视图配置
在Index.cshtml视图顶部声明模型类型,之后直接遍历Model渲染列表即可:
@model List<ExampleViewModel> <table class="table"> <thead> <tr> <th>Example1 ID</th> <th>Attr1</th> <th>Attr2</th> <th>Example1 Attr3</th> <th>Example2 ID</th> <th>Example2 Attr3</th> <th>Attr4</th> <th>Attr5</th> <th>Example3 ID</th> <th>Attr6</th> <th>Attr7</th> <th>Attr8</th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr> <td>@item.ID_Ex1</td> <td>@item.Attr1</td> <td>@item.Attr2</td> <td>@item.Ex1_Attr3</td> <td>@item.ID_Ex2</td> <td>@item.Ex2_Attr3</td> <td>@item.Attr4</td> <td>@item.Attr5</td> <td>@item.ID_Ex3</td> <td>@item.Attr6</td> <td>@item.Attr7</td> <td>@item.Attr8</td> </tr> } </tbody> </table>
其他可选实现方案
- 引入AutoMapper等对象映射库:当模型属性较多、映射规则固定时,不需要手写逐属性赋值的代码,配置好映射规则后可直接完成原始模型到ViewModel的转换,减少重复代码。
- 使用聚合根ViewModel:如果三个模型的数据不需要做关联拍平,只是在同一个页面独立展示,可以直接定义包含三个集合属性的ViewModel,不需要做关联映射,直接把三个原始列表赋值给对应属性传给视图即可,适合数据独立展示的场景:
public class MultiSectionViewModel { public List<Example1> Section1Data { get; set; } public List<Example2> Section2Data { get; set; } public List<Example3> Section3Data { get; set; } } - 轻量场景可以直接用ViewBag/ViewData传递列表:不需要单独定义ViewModel,直接把组装好的列表存入ViewBag传到视图,但这种方式没有强类型智能提示,排错成本高,不推荐正式项目使用。
提示:如果你的非数据库数据需要复用,可以封装成独立的服务类注册到DI容器,不需要在控制器里写死数据源读取逻辑,方便后续维护。
内容的提问来源于stack exchange,提问作者ChilliCandy
相关产品推荐
相关产品推荐

