EF Core: 无法在应用客户端投影之后翻译设置操作

huangapple go评论64阅读模式
英文:

EF Core: Unable to translate set operation after client projection has been applied

问题

我目前正在使用Entity Framework Core开发一个项目,遇到了LINQ查询的问题。在EF的旧版本(EF-6)中,这个查询运行良好,但在升级到最新版本(EF Core-7)后,我遇到了以下异常:

> “在应用客户端投影后无法翻译集操作。考虑将集操作移至最后的 'Select' 调用之前。”

以下是有问题的代码:

var qTypes = DbRead.datas.AsNoTracking().Where(x => SelectionTypes.Contains(x.type));

var q1 = qTypes
    .GroupBy(x => x.type)
    .Select(g => g.Where(x => x.timestamp <= fromTimestamp).OrderByDescending(x => x.timestamp).FirstOrDefault());

var q2 = qTypes.Where(x => x.timestamp > fromTimestamp && x.timestamp <= toTimestamp);

var qResult = q1.Union(q2).OrderBy(x => x.timestamp).ThenBy(x => x.type);

var entries = new List<SelectionEntry>();

foreach (var entity in qResult)
{
    if (entity is null)
    {
        continue; // 跳过 - 由于q1中的FirstOrDefault引起
    }

    entries.Add(FromSelectionEntity(entity));
}
return entries;

我尝试了不同的方法来重构查询,但没有成功。对于如何解决这个问题的任何建议或见解将不胜感激。

在此先感谢您的帮助!

英文:

I'm currently working on a project using Entity Framework Core and I've come across an issue with a LINQ query. The query worked fine in previous versions of EF
(EF -6) but after upgrading to the latest version (EF core -7), I'm getting the following exception:

> "Unable to translate set operation after client projection has been applied. Consider moving the set operation before the last 'Select' call."

Here is the problematic code

var qTypes = DbRead.datas.AsNoTracking().Where(x => SelectionTypes.Contains(x.type));

var q1 = qTypes
    .GroupBy(x => x.type)
    .Select(g => g.Where(x => x.timestamp <= fromTimestamp).OrderByDescending(x => x.timestamp).FirstOrDefault());

var q2 = qTypes.Where(x => x.timestamp > fromTimestamp && x.timestamp <= toTimestamp);

var qResult = q1.Union(q2).OrderBy(x => x.timestamp).ThenBy(x => x.type);

var entries = new List<SelectionEntry>();

foreach (var entity in qResult)
{
    if (entity is null)
    {
        continue; // skip - caused by the FirstOrDefault in q1 above
    }

    entries.Add(FromSelectionEntity(entity));
}
return entries;

I have tried different approaches to restructure the query but without success. Any suggestions or insights on how to resolve this issue would be greatly appreciated.

Thank you in advance for your help!

答案1

得分: 1

尝试以下解决方法:

var qTypes = DbRead.datas.AsNoTracking().Where(x => SelectionTypes.Contains(x.type));

var q1Filtered = qTypes.Where(x => x.timestamp <= fromTimestamp);
var q1 = 
    from d in q1Filtered.Select(d => new { d.Type }).Distinct()
    from q in q1Filtered
        .Where(q => q.Type == d.Type)
        .OrderByDescending(x => x.timestamp)
        .Take(1)
    select q;

var q2 = qTypes.Where(x => x.timestamp > fromTimestamp && x.timestamp <= toTimestamp);

var qResult = q1.Union(q2).OrderBy(x => x.timestamp).ThenBy(x => x.type);

var entries = qResult.Select(entity => FromSelectionEntity(entity)).ToList();
return entries;

注意:我已经将HTML转义字符(如&gt;&lt;)替换为正常的代码比较运算符。

英文:

Try the following workaround:

var qTypes = DbRead.datas.AsNoTracking().Where(x =&gt; SelectionTypes.Contains(x.type));

var q1Filtered = qTypes.Where(x =&gt; x.timestamp &lt;= fromTimestamp);
var q1 = 
    from d in q1Filtered.Select(d =&gt; new { d.Type }).Distinct()
    from q in q1Filtered
      .Where(q =&gt; q.Type == d.Type)
      .OrderByDescending(x =&gt; x.timestamp)
      .Take(1)
    select q;

var q2 = qTypes.Where(x =&gt; x.timestamp &gt; fromTimestamp &amp;&amp; x.timestamp &lt;= toTimestamp);

var qResult = q1.Union(q2).OrderBy(x =&gt; x.timestamp).ThenBy(x =&gt; x.type);

var entries = qResult.Select(entity =&gt; FromSelectionEntity(entity)).ToList();
return entries;

huangapple
  • 本文由 发表于 2023年6月19日 01:30:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76501779.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定