升级到.NET Core 3.1,并在LINQ查询中收到与使用.FirstOrDefault相关的错误

问题描述

我有一个Entity Framework控制器,该控制器已成功使用以下方法。但是,我最近将项目更新为使用.NET Core 3.1,它肯定已经损坏了某些东西。

我现在收到此错误

FirstOrDefault()'无法翻译。以一种可以翻译的形式重写查询,或者通过插入对AsEnumerable(),AsAsyncEnumerable(),ToList()或ToListAsync()的调用来显式切换到客户端评估

我做了一些研究,有人说不要使用GroupBy扩展名,我在下面的查询中做了。我尝试将其取出,但这只会产生更多错误

我也去了this

但是我不知道如何解决下面的复杂查询

老实说,我不确定为什么它会失败或如何正确修复它。

有人看错吗?

谢谢!

 public async Task<ActionResult<object>> GetStarChemicalData(string starID)
        {
            var starChemicalData = await (from starlist in _context.StarList
                                          join ql in _context.ChemicalList on starlist.ChemicalId equals ql.ChemicalId into stars
                                          from chemicallist in stars.DefaultIfEmpty()
                                          join qc in _context.ChemicalAtoms on chemicallist.ChemicalId equals qc.ChemicalId into chemicals
                                          from chemicalatoms in chemicals.DefaultIfEmpty()
                                          join nk in _context.StarLinks on chemicalatoms.AtomId equals nk.AtomId into links
                                          from starlinks in links.DefaultIfEmpty()
                                          where starlist.StarId == starID
                                          select new
                                          {
                                              StarId = starlist.StarId,StarType = starlist.StarType,StarTitle = starlist.StarTitle,ChemicalId = starlist.ChemicalId,AtomId = (Guid?)chemicalatoms.AtomId,OrderId = chemicalatoms.OrderId,ChemicalText = chemicallist.ChemicalText,AtomText = chemicalatoms.AtomText,Wavelength = chemicalatoms.Wavelength,isRedShifted = (starlinks.AtomId != null && starlist.StarType == 1) ? 1
                                              : (starlinks.AtomId == null && starlist.StarType == 1) ? 0
                                              : (int?)null
                                          })
                                              .GroupBy(x => x.StarId)
                                              .Select(g => new
                                              {
                                                  StarId = g.FirstOrDefault().StarId,StarType = g.FirstOrDefault().StarType,StarTitle = g.FirstOrDefault().StarTitle,ChemicalId = g.FirstOrDefault().ChemicalId,ChemicalText = g.FirstOrDefault().ChemicalText,ChemicalAtoms = (g.FirstOrDefault().AtomId != null ? g.Select(x => new
                                                  {
                                                      AtomId = x.AtomId,OrderId = x.OrderId,AtomText = x.AtomText,Feedback = x.Wavelength,IsCorrect = x.isRedShifted
                                                  }) : null)
                                              }).FirstOrDefaultAsync();

            return starChemicalData;

调试后发生错误

.Select(x => new { 
    AtomId = x.AtomId,IsCorrect = x.isRedShifted
 })' Could not be translated.

解决方法

您有许多FirstOrDefault(s)呼叫。

要对其进行“安全”编码,您可以尝试以下操作:

.FirstOrDefault() ?? string.Empty

.FirstOrDefault() ?? 0

.. 上面是它的简写形式:(空检查+?三元运算符)(再次,这是一种“安全”的编码方式)

StarId = null == g.FirstOrDefault() ? 0 : g.FirstOrDefault().StarId,StarType = null == g.FirstOrDefault() ? string.Empty : g.FirstOrDefault().StarType,StarTitle = null == g.FirstOrDefault() ? string.Empty : g.FirstOrDefault().StarTitle,

..

但是更好地进行调试,以找出错误所在

将所有这些(临时性)更改为“”和0

我列出了3个,但是您应该全部更改

代替此:

StarId = g.FirstOrDefault().StarId,StarType = g.FirstOrDefault().StarType,StarTitle = g.FirstOrDefault().StarTitle,

(暂时)使用此:

   StarId = 0,StarType = "",StarTitle = "",

(再次执行所有操作)

然后一个接一个地将它们放回去

    StarId = g.FirstOrDefault().StarId,

找到“罪魁祸首”。

这是一些伪代码.......您可以尝试使用IQueryable的中间步骤。它的pseduo代码,您必须进行调整。

IQueryable是一种“缓慢建立查询”的方法,而不是编写单个超级查询.....并且有助于调试。最终,您将注释掉(或删除)... tempDebuggingCollection ........但它可以帮助您到达要去的地方。

public async Task<ActionResult<object>> GetStarChemicalData(string starID)
        {
            IQueryable<YourObjectHere> starChemicalDataQueryable = await (from starlist in _context.StarList
                                          join ql in _context.ChemicalList on starlist.ChemicalId equals ql.ChemicalId into stars
                                          from chemicallist in stars.DefaultIfEmpty()
                                          join qc in _context.ChemicalAtoms on chemicallist.ChemicalId equals qc.ChemicalId into chemicals
                                          from chemicalatoms in chemicals.DefaultIfEmpty()
                                          join nk in _context.StarLinks on chemicalatoms.AtomId equals nk.AtomId into links
                                          from starlinks in links.DefaultIfEmpty()
                                          where starlist.StarId == starID;
                                    
            ICollection<YourObjectHere> tempDebuggingCollection = starChemicalDataQueryable.ToListAsync(CancellationToken.None);
                                    
                    
            var starChemicalData = starChemicalDataQueryable
                                        select new
                                          {
                                              StarId = starlist.StarId,StarType = starlist.StarType,StarTitle = starlist.StarTitle,ChemicalId = starlist.ChemicalId,AtomId = (Guid?)chemicalatoms.AtomId,OrderId = chemicalatoms.OrderId,ChemicalText = chemicallist.ChemicalText,AtomText = chemicalatoms.AtomText,Wavelength = chemicalatoms.Wavelength,isRedShifted = (starlinks.AtomId != null && starlist.StarType == 1) ? 1
                                              : (starlinks.AtomId == null && starlist.StarType == 1) ? 0
                                              : (int?)null
                                          })
                                              .GroupBy(x => x.StarId)
                                              .Select(g => new
                                              {
                                                  StarId = g.FirstOrDefault().StarId,ChemicalId = g.FirstOrDefault().ChemicalId,ChemicalText = g.FirstOrDefault().ChemicalText,ChemicalAtoms = (g.FirstOrDefault().AtomId != null ? g.Select(x => new
                                                  {
                                                      AtomId = x.AtomId,OrderId = x.OrderId,AtomText = x.AtomText,Feedback = x.Wavelength,IsCorrect = x.isRedShifted
                                                  }) : null)
                                              }).FirstOrDefaultAsync();                                       
  

            return starChemicalData;

............

再次,同样进行安全检查:

               ChemicalAtoms = (g.FirstOrDefault().AtomId != null ? g.Select(x => new
                                              {
                                                  AtomId = x.AtomId,IsCorrect = x.isRedShifted
                                              }) : null)

您不能安全地检查g.FirstOrDefault()...。

类似这样的东西:

         ChemicalAtoms = null == g.FirstOrDefault() ? null : (g.FirstOrDefault().AtomId != null ? g.Select(x => new
                                              {
                                                  AtomId = x.AtomId,IsCorrect = x.isRedShifted
                                              }) : null)