Как вернуть общий список коллекции в C #? - PullRequest
5 голосов
/ 21 декабря 2009

У меня есть метод linq to sql, и когда он выполняет запрос, он возвращает анонимный тип.

Я хочу вернуть этот анонимный тип обратно на мой сервисный уровень, чтобы немного поработать над логикой.

Я не знаю, как вернуть его.

Я думал, что смогу сделать это

public List<T> thisIsAtest()
{
     return query;
}

но я получаю эту ошибку

Error   1   The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?)

Так что не уверен, какая сборка мне не хватает или это даже тот случай.

Спасибо

EDIT

Хорошо, моя первая проблема была решена, но теперь у меня есть новая проблема, которую я не знаю, как ее исправить, так как я мало знаю об анонимных типах.

Я получаю эту ошибку

Невозможно неявно преобразовать тип 'System.Collections.Generic.List' в System.Collections.Generic.List

Вот запрос

   DbContext.Table.Where(u => u.Table.UserId == userId && u.OutOFF != 0)
       .GroupBy(u => new { u.Table.Prefix })
       .Select(group => new { prefix = group.Key, 
                              Marks = group.Sum(item => (item.Mark * item.Weight) / item.OutOFF) })
       .ToList();

Редактировать 2

public class ReturnValue
{
   string prefix { get; set; }
   decimal? Marks { get; set; } 
}

public List<ReturnValue> MyTest(Guid userId)
{
   try
   {
       var result = dbContext.Table.Where(u => u.Table.UserId == userId && u.OutOFF != 0).GroupBy(u => new { u.Table.Prefix })
       .Select(group => new { prefix = group.Key, Marks = group.Sum(item => (item.Mark * item.Weight) / item.OutOFF) }).ToList();
       return result;
   }
   catch (SqlException)
   {
       throw;
   }

у выбора есть это

Anonymous Types:

a is new{string Prefix}
b is new{ 'a prefix, decimal? marks}

Ответы [ 4 ]

8 голосов
/ 21 декабря 2009

Вы не можете - точка. Вы не можете использовать анонимные типы вне своей области действия, например, вы не можете вернуть их как возвращаемые значения из метода.

Если вам нужно вернуть их, вам нужно определить новый конкретный класс вместо анонимного типа и использовать его вместо анонимного типа.

См. блог Рика Страля о области действия анонимных типов и см. Здесь документы MSDN , в которых четко указано:

Анонимный тип имеет область действия метода. к передать анонимный тип или коллекция, которая содержит анонимный типы, вне границы метода, вы сначала должен привести тип к объекту. Однако это побеждает сильных типизация анонимного типа. если ты необходимо сохранить результаты запроса или передать они вне границы метода, рассмотреть возможность использования обычного имени структура или класс вместо анонимный тип.

ОК, конечно, есть грязные и ужасные хаки, которые действительно возвращают анонимные типы. Но если Microsoft MSDN И Джон Скит не одобрит эту практику, тогда - просто не делайте этого . По определению и намерению анонимные типы связаны с методом, в котором они определены.

ОБНОВЛЕНИЕ для chobo2: я не знаю, каковы ваши типы данных - просто догадываюсь - но предполагая, что "префикс" является целым числом, а "метки" - десятичным, вы можете определить новый класс:

public class ReturnValue
{
    int prefix { get; set; }
    decimal Marks { get; set; } 
}  

и тогда ваш код будет методом, который возвращает List<ReturnValue>:

public List<ReturnValue> thisIsAtest()
{
   DbContext.Table.Where(u => u.Table.UserId == userId && u.OutOFF != 0)
     .GroupBy(u => new { u.Table.Prefix })
     .Select(group => new ReturnValue 
                          { prefix = group.Key, 
                            Marks = group
                              .Sum(item => (item.Mark * item.Weight) / item.OutOFF) })
     .ToList();
}

Ключ здесь: в вашем методе .Select вместо создания нового экземпляра анонимного типа:

     .Select(group => new { prefix = group.Key, marks = .... }

вы создаете экземпляр конкретного типа:

     .Select(group => new ReturnValue { prefix = group.Key, marks = .... }

Таким образом, у вас будет конкретный класс ReturnValue - назовите то, что вам нравится, - и тогда вы можете легко вернуть список этого типа и использовать этот тип в другом месте.

8 голосов
/ 21 декабря 2009
public List<T> thisIsAtest<T>()
{
     return query;
}
2 голосов
/ 21 декабря 2009

Вы хотите вернуть анонимный тип из обычного метода? Я вполне уверен, что вы можете с Reflection, но не было бы безопасности типов и целый ряд других проблем. Не говоря уже о том, что это выглядит странно с точки зрения кодов вызова. Я думаю, что вам придется вернуть объект.

Вам лучше использовать класс или структуру и поместить туда значения.

0 голосов
/ 21 декабря 2009

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

Вы можете передать их обратно как простые объекты, но затем вы потеряете информацию о типе. Я видел некоторые решения, передающие анонимный тип; но они используют отражение, чтобы получить свойства на более позднем этапе.

...