迁移到 ASP.Net Core 3 后如何更改此查询
How can I change this query after migrating to ASP.Net Core 3
Could not be translated... See go.microsoft.com/fwlink/?linkid=2101038
我不能再使用 Include()
了吗?我开始使用原始 SQL 命令会更好吗?
public async Task<IActionResult> Index(int? id)
{
if (id == null)
{
id = 1;
}
var pianoContext = _context.Product
.Include(p => p.IdProductCategoryNavigation)
.Include(p => p.IdProductTamNavigation)
.Include(p => p.IdProductTypeNavigation)
.Where(m => m.IdProductCategory == id || m.IdProductCategoryNavigation.IdPa.Value == 1)
.Where(m => m.IsAt.Equals(true))
.GroupBy(m => m.Name)
.Select(m => m.First());
if (pianoContext == null)
{
return NotFound();
}
return View(await pianoContext.ToListAsync());
}
Can't I use Include() anymore? Is it better I start to using raw SQL commands?
这与 Include()
无关,但因为您正在使用 GroupBy(m=> m.Name)
。参见 breaking chagnes。
这里是关于 Groupby
的描述,引用自 official docs:
The SQL GROUP BY is restrictive too. It requires you to group only by scalar values.The projection can only contain grouping key columns or any aggregate applied over a column. EF Core identifies this pattern and translates it to the server
要解决该问题,您应该使用可以翻译成 SQL:
的 GroupBy()
// a lazy query that will be used to query the ids of Product
var theProductIds =
_context.Product
.Where(m => m.IdProductCategory == id || m.IdProductCategoryNavigation.IdPa.Value == 1)
.Where(m => m.IsAt.Equals(true))
.GroupBy(m => m.Name)
.Select(m => m.Min(p=>p.Id));
// a query that includes all the related navigation properties
var products = await _context.Product
.Where(p => theProductIds.Contains(p.Id))
.Include(p => p.IdProductCategoryNavigation)
.Include(p => p.IdProductTamNavigation)
.Include(p => p.IdProductTypeNavigation)
.ToListAsync();
if(products.Count==0){ return NotFound(); }
return View(products);
上面的查询将被翻译成如下的 SQL 语句:
SELECT [p].[Id], [p].[CategoryId], [p].[Name], ...
FROM [Product] AS [p]
INNER JOIN [ProductCategory] AS [p0] ON [p].[CategoryId] = [p0].[Id]
INNER JOIN ...
WHERE [p].[Id] IN (
SELECT MIN([p1].[Id])
FROM [Product] AS [p1]
INNER JOIN [ProductCategory] AS [p2] ON [p1].[CategoryId] = [p2].[Id]
WHERE ...
GROUP BY [p1].[Name]
)
Could not be translated... See go.microsoft.com/fwlink/?linkid=2101038
我不能再使用 Include()
了吗?我开始使用原始 SQL 命令会更好吗?
public async Task<IActionResult> Index(int? id)
{
if (id == null)
{
id = 1;
}
var pianoContext = _context.Product
.Include(p => p.IdProductCategoryNavigation)
.Include(p => p.IdProductTamNavigation)
.Include(p => p.IdProductTypeNavigation)
.Where(m => m.IdProductCategory == id || m.IdProductCategoryNavigation.IdPa.Value == 1)
.Where(m => m.IsAt.Equals(true))
.GroupBy(m => m.Name)
.Select(m => m.First());
if (pianoContext == null)
{
return NotFound();
}
return View(await pianoContext.ToListAsync());
}
Can't I use Include() anymore? Is it better I start to using raw SQL commands?
这与 Include()
无关,但因为您正在使用 GroupBy(m=> m.Name)
。参见 breaking chagnes。
这里是关于 Groupby
的描述,引用自 official docs:
The SQL GROUP BY is restrictive too. It requires you to group only by scalar values.The projection can only contain grouping key columns or any aggregate applied over a column. EF Core identifies this pattern and translates it to the server
要解决该问题,您应该使用可以翻译成 SQL:
的GroupBy()
// a lazy query that will be used to query the ids of Product
var theProductIds =
_context.Product
.Where(m => m.IdProductCategory == id || m.IdProductCategoryNavigation.IdPa.Value == 1)
.Where(m => m.IsAt.Equals(true))
.GroupBy(m => m.Name)
.Select(m => m.Min(p=>p.Id));
// a query that includes all the related navigation properties
var products = await _context.Product
.Where(p => theProductIds.Contains(p.Id))
.Include(p => p.IdProductCategoryNavigation)
.Include(p => p.IdProductTamNavigation)
.Include(p => p.IdProductTypeNavigation)
.ToListAsync();
if(products.Count==0){ return NotFound(); }
return View(products);
上面的查询将被翻译成如下的 SQL 语句:
SELECT [p].[Id], [p].[CategoryId], [p].[Name], ...
FROM [Product] AS [p]
INNER JOIN [ProductCategory] AS [p0] ON [p].[CategoryId] = [p0].[Id]
INNER JOIN ...
WHERE [p].[Id] IN (
SELECT MIN([p1].[Id])
FROM [Product] AS [p1]
INNER JOIN [ProductCategory] AS [p2] ON [p1].[CategoryId] = [p2].[Id]
WHERE ...
GROUP BY [p1].[Name]
)