C# 如何转换通用列表<;匿名类型>;到通用列表<;子菜单>;?

C# 如何转换通用列表<;匿名类型>;到通用列表<;子菜单>;?,c#,linq,C#,Linq,我在将var类型转换为列表时遇到问题。 首先,我从数据库中选择数据,这是确定的!!!!。我收到了带有var变量的数据,但无法将var类型转换为List数据类型 这是我的LINQ声明: var ss = db .SubToSubMenus .Join( db.MenuPermissions, s => s.ID, p =>

我在将var类型转换为
列表
时遇到问题。 首先,我从数据库中选择数据,这是确定的!!!!。我收到了带有
var
变量的数据,但无法将
var
类型转换为
List
数据类型

这是我的LINQ声明:

    var ss =
        db
            .SubToSubMenus
            .Join(
                db.MenuPermissions,
                s => s.ID,
                p => p.SubToSubMenuId,
                (s, p) => new { s, p })
            .Where(w => w.s.Active == true && w.p.RoleId == roleId && w.p.hasPermission == true)
            .Select(s => new
            {
                ID = s.s.ID,
                SubToSubMenuName = s.s.SubToSubMenuName,
                Description = s.s.Description,
            })
            .ToList();
这是
子菜单
类:

[Table("SubToSubMenus")]
public class SubToSubMenu : AceEntityBase
{
    public SubToSubMenu()
    { }
    [Key]
    public string ID { get; set; }
    public string SubToSubMenuName { get; set; }
    public string Description { get; set; }
    public string SubMenuID { get; set; }
}

var
不是一种类型,它是一种语法糖。您的匿名类型与
子菜单
类型没有任何关系

而不是投射到匿名类型:

.Select(s => new { ... })
投影到所需的类型:

.Select(s => new SubToSubMenu { ... })

var
不是一种类型,它是一种语法糖。您的匿名类型与
子菜单
类型没有任何关系

而不是投射到匿名类型:

.Select(s => new { ... })
投影到所需的类型:

.Select(s => new SubToSubMenu { ... })
试试这个:

    var ss =
        db
            .SubToSubMenus
            .Join(
                db.MenuPermissions,
                s => s.ID,
                p => p.SubToSubMenuId,
                (s, p) => new { s, p })
            .Where(w => w.s.Active == true && w.p.RoleId == roleId && w.p.hasPermission == true)
            .Select(s => new
            {
                ID = s.s.ID,
                SubToSubMenuName = s.s.SubToSubMenuName,
                Description = s.s.Description,
            })
            .ToList()
            .Select(s => new SubToSubMenu()
            {
                ID = s.ID,
                SubToSubMenuName = s.SubToSubMenuName,
                Description = s.Description,
            })
            .ToList();
我在您的查询末尾添加了一个简单的投影。这是为了使代码尽可能接近您开始时的状态,并帮助将来进行重构

在这种情况下,它当然可以编码为单个投影。

尝试以下方法:

    var ss =
        db
            .SubToSubMenus
            .Join(
                db.MenuPermissions,
                s => s.ID,
                p => p.SubToSubMenuId,
                (s, p) => new { s, p })
            .Where(w => w.s.Active == true && w.p.RoleId == roleId && w.p.hasPermission == true)
            .Select(s => new
            {
                ID = s.s.ID,
                SubToSubMenuName = s.s.SubToSubMenuName,
                Description = s.s.Description,
            })
            .ToList()
            .Select(s => new SubToSubMenu()
            {
                ID = s.ID,
                SubToSubMenuName = s.SubToSubMenuName,
                Description = s.Description,
            })
            .ToList();
我在您的查询末尾添加了一个简单的投影。这是为了使代码尽可能接近您开始时的状态,并帮助将来进行重构


在这种情况下,它当然可以编码为单个投影。

您不需要在这里投影。您已经从数据库中选择了
子菜单
,因此以后不需要在表达式链中“重新创建”类

var ss =
    db
        .SubToSubMenus
        .Join(
            db.MenuPermissions,
            s => s.ID,
            p => p.SubToSubMenuId,
            (s, p) => new { s, p })
        .Where(w => w.s.Active == true && w.p.RoleId == roleId && w.p.hasPermission == true)
到目前为止还不错。您已联接了两个表并应用了正确的筛选器

        .Select(s => new
        {
            ID = s.s.ID,
            SubToSubMenuName = s.s.SubToSubMenuName,
            Description = s.s.Description,
        })
        .ToList();
好的,到此为止。如果此查询的最终目标是仅选择子菜单实体,则可以将此部分替换为

.Select(s => s.s);
…并忽略后续语句的其余部分

但是,您也可以更进一步,在EF配置中隐含的
子菜单
菜单超任务
实体之间建立关联,这样您就不需要了。加入LINQ。因此,最终查询应类似于:

var ss = db.SubToSubMenus
    .Where(stsm => stsm.Active
        && stsm.MenuPermissions.RoleId == roleId 
        && stsm.MenuPermissions.HasPermission);

你不应该在这里投射。您已经从数据库中选择了
子菜单
,因此以后不需要在表达式链中“重新创建”类

var ss =
    db
        .SubToSubMenus
        .Join(
            db.MenuPermissions,
            s => s.ID,
            p => p.SubToSubMenuId,
            (s, p) => new { s, p })
        .Where(w => w.s.Active == true && w.p.RoleId == roleId && w.p.hasPermission == true)
到目前为止还不错。您已联接了两个表并应用了正确的筛选器

        .Select(s => new
        {
            ID = s.s.ID,
            SubToSubMenuName = s.s.SubToSubMenuName,
            Description = s.s.Description,
        })
        .ToList();
好的,到此为止。如果此查询的最终目标是仅选择子菜单实体,则可以将此部分替换为

.Select(s => s.s);
…并忽略后续语句的其余部分

但是,您也可以更进一步,在EF配置中隐含的
子菜单
菜单超任务
实体之间建立关联,这样您就不需要了。加入LINQ。因此,最终查询应类似于:

var ss = db.SubToSubMenus
    .Where(stsm => stsm.Active
        && stsm.MenuPermissions.RoleId == roleId 
        && stsm.MenuPermissions.HasPermission);


我试了很多种方法!!!请告诉我正确的方向。列表数据=ss;这样地!!!在发布完整的代码后,您遇到了一些主要的语法错误。我认为,这里有一个泛型
ToList()
重载。某种类型的
ToList()
List()
请记住
var
不是一种类型。这是一个告诉编译器推断真实类型的关键字。我尝试了很多方法!!!请告诉我正确的方向。列表数据=ss;这样地!!!在发布完整的代码后,您遇到了一些主要的语法错误。我认为,这里有一个泛型
ToList()
重载。某种类型的
ToList()
List()
请记住
var
不是一种类型。这是一个告诉编译器推断真实类型的关键字。“Try this”不是答案,也不需要重复投影。为什么先选择匿名类型,然后选择具体类型?我经常发现,为了重构的目的,最好将数据库查询与内存中的转换分开。在这种情况下,这并不重要,但我们确实会尝试运行无法转换为数据库的方法或操作。这是我养成的习惯。@CodeCaster-我已经编辑并解释了我的推理。@CodeCaster如果我记得清楚的话,实体框架不喜欢在映射类上进行投影。因此,在
IQueryable
中选择(s=>新建子菜单()是“错误的”。应该可以在这两个
之间使用
.AsEnumerable()
。选择
,使第二个
。选择
对EF不可见。“试试这个”这不是一个答案,也不需要两次投影。为什么先选择一个匿名类型,然后选择一个具体类型?我经常发现,为了重构的目的,最好将数据库查询与内存中的转换分开。在这种情况下,这不重要,但我们确实会尝试运行方法或opera无法转换为数据库的操作。这是我养成的习惯。@CodeCaster-我已经编辑并解释了我的推理。@CodeCaster如果我记得很清楚的话,实体框架不喜欢在映射类上进行投影。这样做
。在
IQueryable
中选择(s=>新建子菜单()
是“坏的”。应该可以在两个
之间使用
.AsEnumerable()
。选择
,使第二个
。选择
对EF不可见。竖起大拇指。我将给出相同的答案并看到你的答案。竖起大拇指。我将给出相同的答案并看到你的答案。