我有以下SQL查询,该查询恰好按预期返回一行数据:
select count(c.ID) as NoteCount, count(s.ClaimStatusHistoryID) as ActionCount, p.DayGoal
from Collector_Profile p
left join ClaimStatusHistory s on s.AppUserID = p.AppUserID and CONVERT(varchar(10), s.StatusDateTZ, 101) = convert(varchar(10), GETDATE(), 101)
left join Claim_Notes c on c.CollectorID = p.ID and CONVERT(varchar(10),c.PostDateTZ,101) = convert(varchar(10), GETDATE(), 101)
where p.ID = 1338
group by p.DayGoal
我正在尝试转换为LINQ。当我尝试包含DbFunctions.TruncateTime时,出现错误,未定义TruncateTime。因此,在此示例中,我已将其注释掉,但我也需要使其正常工作。这是我到目前为止的内容,可以编译但会引发错误:
var utcNow = DateTimeOffset.UtcNow.Date;
var query = from p in _context.Collector_Profile
join s in _context.ClaimStatusHistory on p.AppUserID
equals s.AppUserID into gs
// && DbFunctions.TruncateTime(s.StatusDateTZ) equals utcNow into gs
join c in _context.Claim_Notes on p.ID
equals c.CollectorID into gc
//&& DbFunctions.TruncateTime(c.PostDateTZ) equals utcNow into gc
from s in gs.DefaultIfEmpty()
from c in gc.DefaultIfEmpty()
where p.ID == CollectorID
group new { gs, gc } by p.DayGoal into grouped
select new UserStatistics { DayGoal = grouped.Key,
NoteCount = grouped.Count(x => x.gc.Any()),
ActionCount = grouped.Count(x => x.gs.Any()) };
return query.FirstOrDefault();
运行它时出现以下错误:
InvalidOperationException: Processing of the LINQ expression 'DbSet<Collector_Profile>
.GroupJoin(
outer: DbSet<ClaimStatusHistory>,
inner: p => p.AppUserID,
outerKeySelector: s => s.AppUserID,
innerKeySelector: (p, gs) => new {
p = p,
gs = gs
})' by 'NavigationExpandingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core. See https://go.microsoft.com/fwlink/?linkid=2101433 for more detailed information.
有人可以帮助我使此linq查询正常工作吗?感谢您的协助和示例。我已经看了很多问题,但是没有一个人在做我发现的事情。
答案 0 :(得分:1)
我认为这应该可行,除非出现DateTimeOffset.Date
和时区问题。
由于EF Core 3仅对转换GroupJoin
(基本上仅转换为LEFT JOIN
)提供了非常有限的支持,因此您必须将查询分为两部分,一个是使用LEFT JOIN
的SQL查询,然后客户端GroupBy
来创建GroupJoin
的效果。
var utcNowDate = DateTimeOffset.UtcNow.Date;
var dbQuery = from p in _context.Collector_Profile
where p.ID == CollectorID
join s in _context.ClaimStatusHistory.Where(s => s.StatusDateTZ.Value.Date == utcNowDate) on p.AppUserID equals s.AppUserID into gs
from s in gs.DefaultIfEmpty()
join c in _context.Claim_Notes.Where(c => c.PostDateTZ.Value.Date == utcNowDate) on p.ID equals c.CollectorID into gc
from c in gc.DefaultIfEmpty()
select new { p.DayGoal, s = s.ClaimStatusHistoryID, c = c.ID };
var query = from psc in dbQuery.AsEnumerable()
group new { psc.s, psc.c } by psc.DayGoal into grouped
select new UserStatistics {
DayGoal = grouped.Key,
NoteCount = grouped.Count(sc => sc.c != null),
ActionCount = grouped.Count(sc => sc.s != null)
};
return query.FirstOrDefault();