c# - 使用 LINQ to Entities 查询具有一对多关系的父子实体并根据父记录中的值检索子记录
问题描述
我有一个 Asp.net MVC 应用程序,它有 3 个类;事件、修改、FieldHistory。Events 与 Modifications 有一对多的关系,Modifications 也与 FieldHistory 有一对多的关系。
活动类别:
public class Event
{
public int EventId { get; set; }
public string EventName { get; set; }
public DateTime? EventDate { get; set; }
}
改装类:
public class Modification
{
public int ModificationId { get; set; }
public int EventId { get; set; }
public virtual Event Event { get; set; }
public string ModificationStatus { get; set; }
}
FieldHistory 类:
public class FieldHistory
{
public int FieldHistoryId { get; set; }
public int ModificationId { get; set; }
public virtual Modification Modification { get; set; }
public int PropValId { get; set; }
public int KeyFieldId { get; set; }
public string FieldName { get; set; }
public string Instructions { get; set; }
public string Format { get; set; }
}
在其中一个索引操作中,我将修改的 IEnumerable 返回到视图,并将它们显示为索引页面中的列表项。
public async Task<ActionResult> Index()
{
var modifications = _applicationDbContext.Modifications.Include(m
=> m.Event)
.Include(m => m.ItemType)
.Include(m => m.ModificationType)
.OrderByDescending(m => m.CurrentUserId);
return View(await modifications.ToListAsync());
}
我想扩展此查询,以便现在我还将根据 Modification 实体的 ModificationStatus 字段显示 Modifications 及其子记录之一。例如,如果修改状态为“Creating”或“Created”,则加载 PropValId 为 1 的 FieldHistory,否则如果状态为“Processing”或“Approved”,则加载 PropValId 为 2 的 FieldHistory 作为其子项。所以在一个列表项中,我应该在一个记录中包含所有 3 个实体:Event、Modification、FieldHistory
我只是 Linq 的初学者,希望这对我来说是又一大步。
解决方案
不确定是否有直接的方法将 ModificationStatus 与 PropValId 联系起来,因此只需使用您在上面传达的内容,显然如果有更多规则,您必须提供额外的规则......也只会采用第一个其他对象类型,但如果您需要所有关联的对象类型,您可以更改它...
我从上面定义的变量修改中提取,当然假设 DbContext 中包含其他对象的表的名称:
var trios = modifications.Select(m => new { Modification = m, // select the modification obj itself
FieldHistory = _applicationDbContext.FieldHistories.FirstOrDefault(fh =>
fh.ModificationId == m.ModificationId && // I am assuming this is required
fh.PropValId == (new List<string> {"Creating", "Created"}.Contains(m.ModificationStatus) ? 1 : 2)),
Event = _applicationDbContext.Events.FirstOrDefault(e => e.EventId == m.EventId)
}).ToList();
这将返回您要查找的内容。如果你愿意,你可以创建一个类,例如:
public class Trio {
public Modification Modification { get; set; }
public FieldHistory FieldHistory { get; set; }
public Event Event { get; set; }
public Trio (Modification modification, FieldHistory fieldHistory, Event @event)
{
this.Modification = modification;
this.FieldHistory = fieldHistory;
this.Event = @event;
}
}
然后改为:
var trios = modifications.Select(m => new Trio(m, // select the modification obj itself
_applicationDbContext.FieldHistories.FirstOrDefault(fh =>
fh.ModificationId == m.ModificationId && // I am assuming this is required
fh.PropValId == (new List<string> {"Creating", "Created"}.Contains(m.ModificationStatus) ? 1 : 2)),
_applicationDbContext.Events.FirstOrDefault(e => e.EventId == m.EventId)
)).ToList();
推荐阅读
- tfs - TFS 2017 将项目添加到看板上的“新项目”
- oracle - oracle DB服务器上客户端进程的内存消耗
- node.js - 启动chrome headless后无法执行命令
- c# - 从另一个泛型方法调用 MaybeNull 泛型方法
- javascript - 使用 Javascript 和 Webpack 加载图像数组?
- sql - REGEXP_LIKE、oracle、sql、查询、理解
- arm - 树莓派模型 3b+ 活动 LED 沿 gpio 4 闪烁
- mysql - 如何在没有行重复的情况下获得结果
- javascript - 正则表达式:匹配模式,除了前面的模式
- wpf - WPF按钮未触发单击事件