如何在我的.net core应用程序中使用linq2db在单个查询中填充父列表中的子列表?

pxiryf3j  于 2023-02-20  发布在  .NET
关注(0)|答案(1)|浏览(147)

我正在尝试查询数据库以返回包含任何附件的转弯报告。我需要按日期返回的转弯报告项目列表,然后对于每个报告,我希望它也返回与转弯报告关联的所有附件。唯一关联它们的方法是按EntryId。
下面是我获取转弯报告的方法:

public List<TurnReportItem> GetTurnReportsByDateShiftAndDept(DateTime shiftStart, int shiftNum, int dept)
{
    try
    {
        List<TurnReportItem> list;
        using (connection)
        {
            list = (from r in connection.VTurnReports
                    join a in connection.TurnReportAreas on r.AreaId equals a.AreaId
                    where a.DeptId == dept && a.Enabled && r.ShiftDate == shiftStart && r.ShiftNum == shiftNum
                    select new TurnReportItem 
                    { 
                        areaId = r.AreaId, 
                        areaName = a.Name, 
                        author = r.Author, 
                        comment = r.Comment, 
                        datetime = r.Datetime, 
                        id = r.EntryId, 
                        ip = r.Ip, 
                        shiftDate = r.ShiftDate, 
                        shiftNum = r.ShiftNum, 
                        sort_order = a.SortOrder, 
                        attachment_count = r.AttachmentCount, 
                        attachments = (
                            from at in connection.TurnReportAttachments where at.EntryId == r.EntryId
                            select new TurnReportAttachment
                            {
                                AttachmentId = at.AttachmentId,
                                FileName = at.FileName
                            }).ToList()
                    })
                   .OrderBy(r => r.sort_order)
                   .OrderBy(r => r.datetime)
                   .ToList();
            return list;
        }
    }

这是我正在填充的TurnReportItem类。如果我没有子查询,我会得到所有的Turnreport。

public class TurnReportItem
{
    public int id;
    public string comment;
    public DateTime datetime;
    public string author;
    public int areaId;
    public string areaName;
    public DateTime shiftDate;
    public int shiftNum;
    public string ip;
    public int? attachment_count;
    public int sort_order;
    public int area_rating;
    public List<TurnReportAttachment> attachments;

    public TurnReportItem() { }
}

我有一个单独的方法,将返回所有的评论与条目ID。我已经尝试使用该方法来填充列表。我从MVC应用程序转换这一点,我能够使用该方法来填充列表,但它不会工作,当我尝试在这个应用程序中,我也宁愿只在数据库中建立一个连接,以获得我需要的。

List<TurnReportItem> list;
using (connection)
{
    list = (from r in connection.VTurnReports
            join a in connection.TurnReportAreas on r.AreaId equals a.AreaId
            where a.DeptId == dept && a.Enabled && r.ShiftDate == shiftStart && r.ShiftNum == shiftNum
            select new TurnReportItem 
            { 
                areaId = r.AreaId, 
                areaName = a.Name, 
                author = r.Author, 
                comment = r.Comment, 
                datetime = r.Datetime, 
                id = r.EntryId, 
                ip = r.Ip, 
                shiftDate = r.ShiftDate, 
                shiftNum = r.ShiftNum, 
                sort_order = a.SortOrder, 
                attachment_count = r.AttachmentCount, 
                attachments = SelectAttachmentsByEntryId(r.EntryId)
            })
           .OrderBy(r => r.sort_order)
           .OrderBy(r => r.datetime)
           .ToList();
    return list;
}

public List<TurnReportAttachment> SelectAttachmentsByEntryId(int EntryId)
{
    using (connection)
    {
        // we do it this way so that we don't return the blob
        var results = from p in connection.TurnReportAttachments
                      where p.EntryId == EntryId
                      select new TurnReportAttachment
                      {
                          EntryId = p.EntryId,
                          AttachmentId = p.AttachmentId,
                          FileName = p.FileName
                      };

        return results.ToList();
    }
}
t40tm48m

t40tm48m1#

在您的情况下,SelectAttachmentsByEntryId应该是静态的,带有额外的参数connection。要使其工作,需要使用ExpressionMethod

public static class ReportHelpers
{
    [ExpressionMethod(nameof(SelectAttachmentsByEntryIdImpl))]
    public static List<TurnReportAttachment> SelectAttachmentsByEntryId(MyConnection connection, int EntryId)
    {
        throw new InvalidOperationException(); // should never enter here
    }

    private static Expression<Func<MyConnection, int, List<TurnReportAttachment>>> SelectAttachmentsByEntryIdImpl()
    {
        return (connection, EntryId) =>
            (from p in connection.TurnReportAttachments
            where p.EntryId == EntryId
            select new TurnReportAttachment
            {
                EntryId = p.EntryId,
                AttachmentId = p.AttachmentId,
                FileName = p.FileName
            })
            .ToList();
    }    
}

然后可以在查询中使用此方法:

public List<TurnReportItem> GetTurnReportsByDateShiftAndDept(DateTime shiftStart, int shiftNum, int dept)
{
    using (connection)
    {
        var list = (from r in connection.VTurnReports
                join a in connection.TurnReportAreas on r.AreaId equals a.AreaId
                where a.DeptId == dept && a.Enabled && r.ShiftDate == shiftStart && r.ShiftNum == shiftNum
                select new TurnReportItem 
                { 
                    areaId = r.AreaId, 
                    areaName = a.Name, 
                    author = r.Author, 
                    comment = r.Comment, 
                    datetime = r.Datetime, 
                    id = r.EntryId, 
                    ip = r.Ip, 
                    shiftDate = r.ShiftDate, 
                    shiftNum = r.ShiftNum, 
                    sort_order = a.SortOrder, 
                    attachment_count = r.AttachmentCount, 
                    attachments = ReportHelpers.SelectAttachmentsByEntryId(connection, r.EntryId)
                })
                .OrderBy(r => r.sort_order)
                .ThenBy(r => r.datetime)
                .ToList();
        return list;
    }
 }

注意,OrderBy.OrderBy没有意义,应该是OrderBy.ThenBy

相关问题