迁移到 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]
)