查询具有一对多关系的父子实体,并使用LINQ to Entities根据父记录中的值检索子记录

时间:2019-06-07 06:04:11

标签: c# entity-framework linq

我有一个Asp.net MVC应用程序,它具有3个类;事件,修改,FieldHistory。事件与修改具有一对多关系,而修改与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; }
}

在其中一个Index动作中,我向视图返回IEnumerable of Modifications,并将它们作为列表项显示在索引页中。

    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及其子记录之一。例如,如果修改状态为“正在创建”或“已创建”,则加载PropValId为1的FieldHistory,否则,如果状态为“正在处理”或“已批准”,则加载PropValId为2的FieldHistory作为其子级。因此,在列表项中,我应该在记录中包含所有3个实体:事件,修改,FieldHistory

我只是Linq的初学者,希望这对我来说可以是又一大步。

1 个答案:

答案 0 :(得分:0)

不确定是否有直接方法将ModificationStatus与PropValId绑定在一起,因此,仅使用您上面传达的内容,显然,如果还有更多内容,则您必须提供其他规则...也只会采用 First 一种其他对象类型,但是如果需要所有相关的对象,则可以更改它...

我从上面定义的变量修改中接手,当然要假设您的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();