Невозможно преобразовать анонимный список в известный список в LINQ

#c# #entity-framework #linq

#c# #entity-framework #linq

Вопрос:

У меня есть запрос LINQ, который возвращает мне результаты из одной таблицы. Мне нужно преобразовать его в список этой табличной модели. Анонимный тип 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 amp;amp; g5.Name != ""
                                select new{ Group = g5}).ToList();

groups = groupManager.Cast<Group>().ToList();
  

Похоже, этот код не работает.Ошибка, которую я получаю, заключается в {«Невозможно преобразовать объект типа ‘<> f__AnonymousType11`1[Group]’ в тип ‘Group’.»} Я что-то упускаю?

Комментарии:

1. Почему вы вообще переносите значение в анонимный объект, если вам просто нужно само значение?

2. GroupManager имеет тип List<Group>() зачем вы вообще пытаетесь его преобразовать?

3. @Servy Как вы думаете, что я должен делать?

4. @The_Outsider Если вам не нужно значение, заключенное в анонимный объект, не заключайте его в анонимный объект. Вы изо всех сил пытаетесь превратить свою группу в анонимный объект, в котором есть группа, а затем спрашиваете, как превратить этот анонимный объект в группу.

5. @The_Outsider — Я даю два способа не включать мой ответ.

Ответ №1:

хммм … вы пробовали это?

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

или это

  select g5).ToList();
  

трудно сказать больше, ничего не зная об объекте group или других типах в вашем примере.

Комментарии:

1. Не работает, потому что мой конструктор Group не принимает параметры. Пробуя второй, позвольте мне проверить

2. @The_Outsider — тогда напишите конструктор, который выполняет, или используйте 2-й пример.

Ответ №2:

Вероятно, вы можете сделать это без анонимного типа или приведения.

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

Комментарии:

1. В таблице много столбцов, наверняка должен быть более простой способ

2. Является ли ваша таблица набором объектов<Group>? Если это так, просто выберите g5, как предложил Хоган. Я предполагал, что это не так, поскольку я думал, что вы добрались бы туда самостоятельно.

Ответ №3:

Предоставленные ответы были абсолютно правильными, но я думаю, было бы неплохо указать на одну тонкую вещь, касающуюся Cast метода (и ответить на вопрос «Я что-то упускаю»). часть).

Cast метод действительно служит другой цели, чем приведение всех объектов в списке к другому типу. Неудивительно, что компилятор выдает это исключение, поскольку то, что Cast делает, берет IEnumerable (не общую версию) и возвращает ту же коллекцию, но с общим IEnumerable<T> значением. Это один из двух методов в LINQ, которые принимают в качестве аргумента не универсальный IEnumerable (второй — OfType ), поэтому вы могли бы иметь коллекцию заданного типа, привести ее к IEnumerable<T> и использовать другие методы LINQ, которые требуют IEnumerable<T> в качестве аргумента.

Просто посмотрите на исходный код

 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 работать. Он не приведет ваши анонимные типы к конкретным типам.

Комментарии:

1. Вау, это глубоко. Мне это нравится.

Ответ №4:

Если вы выберете фактический объект, то это то, что вы получите обратно в виде IEnumerable of Group:

 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 amp;amp; g5.Name != ""
                            select g5).ToList()
groups = groupManager;
  

The .Затем ToList () преобразует его в список. Нет необходимости создавать динамический объект и затем приводить.