升级到 .NET Core 3.1 并在与使用 .FirstOrDefault() 相关的 LINQ 查询中收到错误
Upgraded to .NET Core 3.1 and receiving an error in a LINQ query related to using .FirstOrDefault()
我有一个 Entity Framework 控制器成功地使用了下面的方法。但是,我最近更新了我的项目以使用 .NET Core 3.1,它一定有问题。
我现在收到这个错误:
FirstOrDefault()' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or 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,
OrderId = x.OrderId,
AtomText = x.AtomText,
Feedback = x.Wavelength,
IsCorrect = x.isRedShifted
})' could not be translated.
您有很多 FirstOrDefault (s) 调用。
要“安全地”对它们进行编码,您可以尝试这样做:
.FirstOrDefault() ?? string.Empty
或
.FirstOrDefault() ?? 0
..
上面是这个的简写版本:(null check + ? 三元运算符)(同样,这是一种“安全”的编码方式)
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 = "",
(再次全部完成)
和one-by-one,将它们替换回去
StarId = g.FirstOrDefault().StarId,
StarType = "",
StarTitle = "",
找到“罪魁祸首”
这里是一些伪代码.......你可以尝试使用 IQueryable 的中间步骤。它的伪代码,你必须调整。
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,
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;
.......
AGain,同样的安全检查:
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)
您没有安全地检查 g.FirstOrDefault() ....
像这样:
ChemicalAtoms = null == g.FirstOrDefault() ? null : (g.FirstOrDefault().AtomId != null ? g.Select(x => new
{
AtomId = x.AtomId,
OrderId = x.OrderId,
AtomText = x.AtomText,
Feedback = x.Wavelength,
IsCorrect = x.isRedShifted
}) : null)
我有一个 Entity Framework 控制器成功地使用了下面的方法。但是,我最近更新了我的项目以使用 .NET Core 3.1,它一定有问题。
我现在收到这个错误:
FirstOrDefault()' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or 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,
OrderId = x.OrderId,
AtomText = x.AtomText,
Feedback = x.Wavelength,
IsCorrect = x.isRedShifted
})' could not be translated.
您有很多 FirstOrDefault (s) 调用。
要“安全地”对它们进行编码,您可以尝试这样做:
.FirstOrDefault() ?? string.Empty
或
.FirstOrDefault() ?? 0
.. 上面是这个的简写版本:(null check + ? 三元运算符)(同样,这是一种“安全”的编码方式)
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 = "",
(再次全部完成)
和one-by-one,将它们替换回去
StarId = g.FirstOrDefault().StarId,
StarType = "",
StarTitle = "",
找到“罪魁祸首”
这里是一些伪代码.......你可以尝试使用 IQueryable 的中间步骤。它的伪代码,你必须调整。
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,
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;
.......
AGain,同样的安全检查:
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)
您没有安全地检查 g.FirstOrDefault() ....
像这样:
ChemicalAtoms = null == g.FirstOrDefault() ? null : (g.FirstOrDefault().AtomId != null ? g.Select(x => new
{
AtomId = x.AtomId,
OrderId = x.OrderId,
AtomText = x.AtomText,
Feedback = x.Wavelength,
IsCorrect = x.isRedShifted
}) : null)