[英]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.