Как вернуть анонимный тип из метода С#, который использует LINQ to SQL

Возможный дубликат:
LINQ to SQL: вернуть анонимный тип?

У меня есть стандартный запрос LINQ to SQL, который возвращает данные как анонимный тип (содержащий около 6 столбцов данных различных типов данных).

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

Как я могу это сделать, учитывая, что это анонимный тип ( "var" )?

EDIT - вот код:

    using (ormDataContext context = new ormDataContext(connStr))
    {
        var electionInfo = from t1 in context.elections
                   join t2 in context.election_status
                   on t1.statusID equals t2.statusID
                   select new { t1, t2 };
    }

Ответ 1

Сделайте анонимный тип в класс...

public class Person
{
    public Person() {
    }

    public String Name { get; set; }
    public DateTime DOB { get; set; }
}


Person p = 
    from person in db.People 
    where person.Id = 1 
    select new Person { 
        Name = person.Name,
        DOB = person.DateOfBirth
    }

Ответ 2

Вы не можете вводить какой-либо метод в С# для явного типа анонимных типов. Они не могут быть "названы" так сказать и, следовательно, не могут появляться в подписях метаданных.

Если вы действительно хотите вернуть значение, которое является анонимным, есть 2 варианта

  • Тип возвращаемого метода должен быть System.Object. Затем вы можете делать злые махинации, чтобы получить типизированное значение в другом методе. Это очень хрупкий, и я не рекомендую его.
  • Используйте общий метод и трюк вывода типа, чтобы получить правильный тип возвращаемого значения. Это потребует очень интересного определения подписи для вашего подхода.

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

Ответ 3

Использование var не делает его анонимным. Использование var просто означает, что эта переменная имеет тип, доступный в правой части задания. Это просто короткая рука. Если предмет в правой части является реальным классом, переменная будет такого типа.

Например:

var person = new Person { Name = "bob" };

Лицевая переменная имеет тип Person, хотя используется ключевое слово var.

Анонимные типы создаются с использованием нового {Name =...}. В этом случае это новый анонимный класс. Единственное, что вы можете назначить, это переменная, определенная с использованием var (или object), поскольку для ее использования не существует существующего имени.

Например:

var person = new { Name = "bob" };

В этом случае человек является анонимным типом, определенным во время выполнения.

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

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

Ответ 4

Джон Скит написал блог о том, как это сделать, что вполне справедливо называется Horribly Grotty Hack. Как следует из названия, вы действительно не должны искать способы возврата анонимного типа. Вместо этого вы должны создать тип, который можно вернуть, поскольку это правильный способ реализации этой функции.

Поэтому я рекомендую вам создать конкретное определение возвращаемого типа и затем заполнить его в запросе, чтобы он был возвращен.

Ответ 5

Это зависит от того, как код вызова будет использовать данные.

Если вы выполняете простую привязку данных, на самом деле не заботятся о типе (т.е. вам не нужно явно обращаться к свойствам в коде С#), вы можете передать результаты обратно как IEnumberable.

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

В противном случае вам нужно преобразовать анонимный тип в именованный тип.

Ответ 6

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