Entity Framework Core/Razor查询一对多关联数据避免主记录重复方案
解决方案
问题根源
- 现有LINQ查询使用双from子句实现内连接,每匹配到1个附件就生成1条独立记录,消息主体会随附件数量重复返回
- 视图模型
ViewMessageModel仅设计了单附件字段,无法存储一条消息对应的多个附件数据
步骤1:调整视图模型结构,支持一对多关联存储
修改ViewMessageModel,新增附件集合字段:
public class ViewMessageModel { public int id { get; set; } public string subject { get; set; } public string message { get; set; } public DateTime create_date { get; set; } // 存储当前消息关联的所有附件 public List<DocumentItem> Documents { get; set; } = new(); } // 附件独立传输类,按需保留需要的字段 public class DocumentItem { public string fileName { get; set; } public byte[] content { get; set; } }
步骤2:修改LINQ查询逻辑,按消息分组关联附件
方案A(推荐):给实体配置导航属性,使用EF Core预加载
先给MessageModel新增导航属性,EF Core会自动根据外键messageId匹配关联关系:
public class MessageModel { public int id { get; set; } public string subject { get; set; } public string message { get; set; } public DateTime created { get; set; } // 导航属性:一条消息对应多个附件 public List<DocumentModel> Documents { get; set; } = new(); }
查询代码直接使用Include预加载关联附件:
var messages = project.MessagesModel .Include(m => m.Documents) .Select(m => new ViewMessageModel { id = m.id, subject = m.subject, message = m.message, create_date = m.created, Documents = m.Documents.Select(d => new DocumentItem { fileName = d.fileName, content = d.content }).ToList() }) .ToList();
方案B:无需修改实体,直接使用GroupJoin分组查询
如果不想修改原有实体结构,直接用分组连接实现一对多查询:
var messages = (from m in project.MessagesModel join md in project.messageDocument on m.id equals md.messageId into docGroup select new ViewMessageModel { id = m.id, subject = m.subject, message = m.message, create_date = m.created, Documents = docGroup.Select(d => new DocumentItem { fileName = d.fileName, content = d.content }).ToList() }).ToList();
步骤3:调整视图渲染逻辑,嵌套循环输出附件
修改视图代码,外层循环输出消息主体,内层循环输出该消息的所有附件:
@using project.Models; @model List<ViewMessageModel> @foreach (var message in Model) { <div>@message.id</div> <div>@message.subject</div> <div>@message.message</div> <div>@message.create_date</div> <div>附件:</div> @foreach (var doc in message.Documents) { <div>@doc.fileName</div> } <hr /> }
内容的提问来源于stack exchange,提问作者Tumo Maraisane
相关产品推荐
相关产品推荐

