ASP.NET Core 5和EF - InvalidOperationException

7

这个查询的范围,它显示一个按类别分组的导航菜单,其中包括主菜单和子菜单。

LINQPad中运行正常,但Web应用程序显示以下未处理的错误:

InvalidOperationException:无法翻译投影中的集合子查询,因为父查询没有投影其所有表的键列,这些键列在客户端生成结果时是必需的。 当尝试关联无键实体或使用“Distinct”或“GroupBy”操作而不投影所有键列时,可能会发生这种情况。

查询:

var mainMenu = (from c in _unitOfWork.Menu.GetAllQueryable()
                        where c.MenuPadreId == 0
                        select new
                        {
                            Categoria = c.MenuCategoria.Descripcion,
                            CategoriaId = c.MenuCategoriaId
                        }).Distinct();

        var menuNavegacion = from c in mainMenu
                             select new MenuNavegacionCategoriaViewModel
                             {
                                 Categoria = c.Categoria,
                                 CategoriaId = c.CategoriaId,
                                 MenuNavegacionViewModel = (from m in _unitOfWork.Menu.GetAllQueryable()
                                                            where m.MenuPadreId == 0
                                                                  && m.MenuCategoriaId == c.CategoriaId
                                                            select new MenuNavegacionViewModel
                                                            {
                                                                MenuId = m.MenuId,
                                                                MenuPadreId = m.MenuPadreId,
                                                                Descripcion = m.Descripcion,
                                                                Area = m.Area,
                                                                Controlador = m.Controlador,
                                                                Accion = m.Accion,
                                                                TieneUrl = m.TieneUrl,
                                                                CountSubMenu = _unitOfWork.Menu.GetAllQueryable().Count(me => me.MenuPadreId > 0 && me.MenuPadreId == m.MenuId),
                                                                Icono = m.Icono,
                                                                MenuNavegacionSubViewModel = (from s in _unitOfWork.Menu.GetAllQueryable()
                                                                                              where s.MenuPadreId > 0
                                                                                                    && s.MenuPadreId == m.MenuId
                                                                                              group s by new
                                                                                              {
                                                                                                  MenuId = s.MenuId,
                                                                                                  MenuPadreId = s.MenuPadreId,
                                                                                                  Descripcion = s.Descripcion,
                                                                                                  Area = s.Area,
                                                                                                  Controlador = s.Controlador,
                                                                                                  Accion = s.Accion,
                                                                                                  TieneUrl = s.TieneUrl,
                                                                                                  Icono = s.Icono
                                                                                              } into sjoin
                                                                                              select new MenuNavegacionSubViewModel
                                                                                              {
                                                                                                  MenuId = sjoin.Key.MenuId,
                                                                                                  MenuPadreId = sjoin.Key.MenuPadreId,
                                                                                                  Descripcion = sjoin.Key.Descripcion,
                                                                                                  Area = sjoin.Key.Area,
                                                                                                  Controlador = sjoin.Key.Controlador,
                                                                                                  Accion = sjoin.Key.Accion,
                                                                                                  TieneUrl = sjoin.Key.TieneUrl,
                                                                                                  Icono = sjoin.Key.Icono
                                                                                              }).OrderBy(mnsvm => mnsvm.Descripcion).ToList()
                                                            }).OrderBy(mnvm => mnvm.Descripcion).ToList()
                             };

视图模型:

public class MenuNavegacionCategoriaViewModel
{
    public string Categoria { get; set; }
    public int CategoriaId { get; set; }
    public List<MenuNavegacionViewModel> MenuNavegacionViewModel { get; set; }
}

public class MenuNavegacionViewModel
{
    public int MenuId { get; set; }
    public int MenuPadreId { get; set; }
    public string Descripcion { get; set; }
    public string Area { get; set; }
    public string Controlador { get; set; }
    public string Accion { get; set; }
    public List<MenuNavegacionSubViewModel> MenuNavegacionSubViewModel { get; set; }
    public bool TieneUrl { get; set; }
    public int CountSubMenu { get; set; }
    public string Icono { get; set; }
}

public class MenuNavegacionSubViewModel
{
    public int MenuId { get; set; }
    public int MenuPadreId { get; set; }
    public string Descripcion { get; set; }
    public string Area { get; set; }
    public string Controlador { get; set; }
    public string Accion { get; set; }
    public bool TieneUrl { get; set; }
    public string Icono { get; set; }
    public string MenuPadreDescripcion { get; set; }
}

按照分组操作出现同样的错误。


1
你尝试过拆分查询吗?这样你就能更快地定位错误所在了。这段代码不太易读。 - Grizzlly
1
你能添加你的DbContext代码吗?特别是针对你的表的 protected override void OnModelCreating(ModelBuilder modelBuilder) 方法?在modelBuilder中,有没有使用 .HasNoKey() 方法? - Stemado
2个回答

4

这个问题是 EF Core 5.0 中的一个重大变更之一。一些涉及相关集合的查询,同时使用 Distinct 或 GroupBy,现在不再被支持。阅读此文以获取更多信息。


1

你的顶级投影之一(例如MenuNavegacionCategoriaViewModel)从外键列中选择了非空列(比如CategoriaId)。将MenuNavegacionCategoriaViewModel中的CategoriaId设置为可空即可解决问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接