无法在LINQ中将匿名列表强制转换为已知列表

本文关键字:列表 转换 LINQ | 更新日期: 2023-09-27 18:14:09

我有一个LINQ查询,它从一个表中返回结果。我需要将其转换为该表模型的List。groupManager的匿名类型是List<a> where a是{Group g5}

var groups = new List<Group>();
var groupManager = (from a in db.AUsers
                                join b in db.BUsers on a.Id equals b.UserID into group1
                                from g1 in group1.DefaultIfEmpty()
                                join c in db.UserRoles on g1.ID equals c.UserID into group2
                                from g2 in group2.DefaultIfEmpty()
                                join d in db.Roles on g2.RoleID equals d.ID into group3
                                from g3 in group3.DefaultIfEmpty()
                                join e in db.RoleGroups on g3.ID equals e.RoleID into group4
                                from g4 in group4.DefaultIfEmpty()
                                join f in db.Groups on g4.GroupID equals f.ID into group5
                                from g5 in group5.DefaultIfEmpty()
                                where a.Id == user.ID && g5.Name != ""
                                select new{ Group = g5}).ToList();
groups = groupManager.Cast<Group>().ToList();

此代码似乎不起作用。我得到的错误是{"无法将'<>f_AnonymousType11`1[Group]'类型的对象强制转换为'Group'类型。"}我缺少什么吗?

无法在LINQ中将匿名列表强制转换为已知列表

hmmm。。。你试过这个吗?

 select new Group(g5)).ToList();

或者这个

 select g5).ToList();

在不了解示例中的group对象或其他类型的情况下,很难说得更多。

您可以在没有匿名类型或强制转换的情况下完成此操作。

var groups = (from a in db.AUsers
              // Your query...
              select new Group
              {
                  // Properties of Group
                  Name = g5.Name,
                  AnotherProperty = g5.AnotherProperty
              }).ToList();

提供的答案是绝对正确的,但我想指出一个关于Cast方法的微妙之处(并回答"我遗漏了什么吗"部分(可能会很好。

Cast方法的实际用途与将列表中的所有对象强制转换为另一种类型不同。编译器抛出这个异常并不奇怪,因为Cast所做的是获取IEnumerable(非泛型版本(并返回相同的集合,但使用泛型IEnumerable<T>。这是LINQ中以非泛型IEnumerable作为参数的两个方法之一(第二个是OfType(,因此您可以拥有给定类型的集合,将其强制转换为IEnumerable<T>,并使用其他需要IEnumerable<T>作为参数的LINQ方法。

看看源代码

public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source) {
    IEnumerable<TResult> typedSource = source as IEnumerable<TResult>;
    if (typedSource != null) return typedSource;
    if (source == null) throw Error.ArgumentNull("source");
    return CastIterator<TResult>(source);
}

和在CastIterator

foreach (object obj in source) yield return (TResult)obj;

因此,您的集合应该能够被转换为给定的类型T,以便Cast工作。它不会将您的匿名类型强制转换为具体类型。

如果您选择了实际对象,那么这就是您作为Group:的IEnumerable返回的内容

var groups = new List<Group>();
var groupManager = (from a in db.AUsers
                            join b in db.BUsers on a.Id equals b.UserID into group1
                            from g1 in group1.DefaultIfEmpty()
                            join c in db.UserRoles on g1.ID equals c.UserID into group2
                            from g2 in group2.DefaultIfEmpty()
                            join d in db.Roles on g2.RoleID equals d.ID into group3
                            from g3 in group3.DefaultIfEmpty()
                            join e in db.RoleGroups on g3.ID equals e.RoleID into group4
                            from g4 in group4.DefaultIfEmpty()
                            join f in db.Groups on g4.GroupID equals f.ID into group5
                            from g5 in group5.DefaultIfEmpty()
                            where a.Id == user.ID && g5.Name != ""
                            select g5).ToList()
groups = groupManager;

ToList((会将其转换为列表。无需创建动态对象然后进行强制转换。