简体   繁体   English

从SQL到LINQ的半复杂查询投影到ViewModel

[英]SQL to LINQ semi-complex query projecting to ViewModel

I know sql well enough to get by professionally, but i'm still new to linq concepts and even less familiar with lambda syntax. 我非常了解sql,可以熟练地使用它,但是我对linq概念还是陌生的,甚至对lambda语法还不太熟悉。 below is my sql query... I successfully join 2 tables on matching id's and filter my results by a certain status and select only the newest entry based on date. 以下是我的sql查询...我成功地在匹配ID上连接了2个表,并按某种状态过滤了结果,并仅基于日期选择了最新的条目。

select ma.* , mnh.note
from MerchApps ma
join MerchNoteHist mnh on mnh.appid = ma.id
where ma.[Status] != 6 and mnh.CreatedDate = (select max(CreatedDate) from 
MerchantNoteHistories where appid = ma.Id)

The ultimate goal is to project this query to my viewmodel. 最终目标是将此查询投影到我的视图模型中。

public class ViewModelListItem
{
    public int Id { get; set; } 
    public DateTime CreatedDate { get; set; }       
    public ApplicationStatus Status { get; set; }     
    public string RecentNote { get; set; }
   ... //other things that aren't related to the question
}

Issue is: find the correct max usage. 问题是:找到正确的最大用量。

My best attempt at LINQ lambda syntax, what I've been able to piece together after doing research: 我在LINQ lambda语法上的最佳尝试,是我在研究后能够拼凑的:

_db.MerchApps
            .Join(_db.MerchNoteHist,
                ma => ma.Id,
                note => note.AppId,
                (ma, note) => new { MA = ma, Note = note })
                .Include(x => x.MA.User)
                .Where(x => x.MA.Status != ApplicationStatus.Approved)
                .Include(x => x.Note.Note)
                .Where(x => x.Note.CreatedDate == Max(x.Note.CreatedDate) //<--Issue is here, because I can't find the correct max usage.
            .ProjectTo<ViewModelListItem>(_mapperConfig)
            .OrderBy(x => x.Status).ThenBy(x => x.CreatedDate).ToListAsync();

The final step is to lay it all out in a view from a foreach loop that uses the above viewmodel. 最后一步是在使用上述viewmodel的foreach循环的视图中进行布局。

After research and trial-and-error and working through lunch to try to figure this out... I'm a solid 7 hours into this and at my wits end. 经过研究和反复试验,并通过午餐努力解决这一问题……我在此工作了7个小时,实事求是。 Any help at all would be appreciated. 任何帮助将不胜感激。

You should use a GroupJoin instead of Join , this will yield a set of MerchNoteHist (I'm assuming this is the same table as MerchantNoteHistories here) that match the AppId. 您应该使用GroupJoin而不是Join ,这将产生一组MerchNoteHist (我假设这是同一个表MerchantNoteHistories这里)匹配的AppId说。

Then, you can use an aggregate ( Max ) in the resultSelector of the function. 然后,您可以在函数的resultSelector中使用聚合( Max )。

Here's roughly what your code should look like: 您的代码大致如下所示:

_db.MerchApps
        .Where(ma => ma.User.Status != ApplicationStatus.Approved) 
        .GroupJoin(
            _db.MerchNoteHist,
            ma => ma.Id,
            noteList => note.AppId,
            (ma, noteList) => new 
            { 
               MA = ma, 
               Note = noteList.OrderByDescending(n=>n.CreatedDate).First()
            })
            //rest of your logic here

Alternatively you could put this in as the second Where clause: 或者,您可以将其作为第二个Where子句放入:

.Where(x => x.Note.CreatedDate== _db.MerchNoteHist
    .Where(y => y.AppId == x.Note.AppId).OrderByDescending(y => y.CreatedDate)
        .First().CreatedDate)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM