问题描述
我有一个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)