从SQL脚本重新创建LINQ查询时遇到问题

时间:2019-06-15 11:47:41

标签: c# sql entity-framework linq entity-framework-core

我正在努力将SQL查询“转换”为LINQ查询。我的SQL查询如下:

SELECT S.SummonerName, LE.LeaguePoints, LS.DateTime, SUM(LE.LeaguePoints)
FROM LadderEntries LE
JOIN Sumonners S on LE.SummonerId = S.Id
JOIN LadderSnapshots LS on LE.LadderSnapshotId = LS.Id
WHERE LS.Region = 'euw1'
AND DateTime = '2019-06-14 00:00:00'
OR DateTime = '2019-06-13 00:00:00'
and LS.Region = 'euw1'
GROUP BY S.SummonerName

此查询给了我想要的结果。但是,到目前为止,我得到了以下LINQ查询:

from LE in _database.LadderEntries
join S in _database.Sumonners on LE.SummonerId equals S.Id
join LS in _database.LadderSnapshots on LE.LadderSnapshot.Id equals LS.Id
where LS.Region == param.Region && (LS.DateTime == param.Date || LS.DateTime == param.Date.AddDays(-1))
group new {LE, S, LS} by S.SummonerName
into C
select new GetLadderEntryDifferencesEntry
{
    LpDifference = C.Select(a => a.LE.LeaguePoints).Sum(),
    SummonerName = C.Select(a => a.S.SummonerName).FirstOrDefault()
};

但这给了我执行错误InvalidOperationException: Error generated for warning 'Microsoft.EntityFrameworkCore.Query.QueryClientEvaluationWarning: The LINQ expression 'GroupBy([S].SummonerName, new <>f__AnonymousType5'3(LE = [LE], S = [S], LS = [LS]))' could not be translated and will be evaluated locally.'.

我想知道我在做什么错。

注意:如果有区别,我正在使用sqllite和ef core。

2 个答案:

答案 0 :(得分:0)

我相信问题将在于:

&& (LS.DateTime == param.Date || LS.DateTime == param.Date.AddDays(-1))

尝试一下:

var firstDate = param.Date;
var secondDate = param.Date.AddDays(-1);

然后

&& (LS.DateTime == firstDate || LS.DateTime == secondDate)

可能例外: SummonerName = C.Select(a => a.S.SummonerName).FirstOrDefault() 或如何安排分组。

这些实体是否设置了引用,可以简化表达式吗?

var ladderEntryDifferences = _database.LadderSnapshots
    .Where(x =>x.Region = param.Region 
        && (x => x.DateTime == firstDate || x.DateTime == secondDate)
    .GroupBy(x => x.LadderEntry.Summoner.SummonerName)
    .Select( g => new GetLadderEntryDifferencesEntry
    {
        LpDifference = g.Sum(x => x.LeagueEntry.LeaguePoints),
        SummonerName = g.Key // This will be the SummonerName
    }).ToList();

以上是关于结构的猜测,并且是从内存中拉出分组依据的,但是它可能会为您提供一些尝试的思路。如果您的上下文没有在最高级别公开LadderSnapshots,那么您也应该能够从LadderEntry级别进行编写...

答案 1 :(得分:0)

首先,这就是我得到的

&& (LS.DateTime == param.Date || LS.DateTime == param.Date.AddDays(-1))

与下面的linq不同,后者在sql中缺少参数。

from LE in _database.LadderEntries
join S in _database.Sumonners on LE.SummonerId equals S.Id
join LS in _database.LadderSnapshots on LE.LadderSnapshot.Id equals LS.Id
where LS.Region == param.Region && (LS.DateTime == param.Date || LS.DateTime == param.Date.AddDays(-1))
group LE by new {LE.SummonerName, S.SummonerName, LS.SummonerName} 
into C
select new GetLadderEntryDifferencesEntry
{
    LpDifference = C.Select(a => a.LE.LeaguePoints).Sum(),
    SummonerName = C.Select(a => a.S.SummonerName).FirstOrDefault()
};

现在,您可以尝试通过分组方式来做到这一点

Foo MapDictionaryToFoo(IReadOnlyDictionary<string, dynamic> d)
{
    return new Foo
    {
        ID1 = d[nameof(Foo.ID1)],
        ID2 = d[nameof(Foo.ID2)],
        ID3 = d[nameof(Foo.ID3)]
    };
}