Передача данных в ASP.NET MVC с использованием LINQ - чокнутость - PullRequest
3 голосов
/ 09 февраля 2009

Позвольте мне начать с: Я n00b на ASP.NET MVC. Я люблю это, но я n00b.

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

Я видел, как кто-то задавал похожий вопрос ( MVC LINQ to SQL Отображение записи о присоединении к таблице ), и ответ, казалось, заключался в создании нового типа данных для сбора данных из запроса LINQ. Я не понимаю, что могу создать тип var в контроллере и получить доступ к полям членов внутри контроллера, но если я хочу передать эту переменную обратно в мой View, мне нужно создать для этого новый класс.

Вот мой код контроллера:

var vrGoodResults1 = from records in db.Words
                      group records by records.word1 into g
                      select new
                      {
                          strWord = g.Key,
                          intWordCount = g.Count()
                      };
            ViewData["GoodWords"] = vrGoodResults1;
            return View();

И вид выглядит так:

<% foreach (var kvp in (IEnumerable)ViewData["GoodWords"]) %>
<% { %>
        <%= String.Format("{0} was used times", kvp) %> <br />
<% } %>

Какие выходы:

{strWord = cool, intWordCount = 2 } was used times
{strWord = educated, intWordCount = 1 } was used times
{strWord = great, intWordCount = 1 } was used times
{strWord = smart, intWordCount = 6 } was used times
{strWord = strong, intWordCount = 2 } was used times
{strWord = super smart, intWordCount = 2 } was used times

Итак, данные попадают в представление, но я не могу ссылаться на данные по именам полей, которые я назначил в запросе LINQ. Когда я пытаюсь сбросить kvp.GetType (), я получаю:

<>f__AnonymousType1`2[System.String,System.Int32]

Все, что я хочу сделать, это что-то вроде:

<%= String.Format("{0} was used {1} times", kvp.strWord, kvp.intWordCount) %> <br />

Но я получаю ошибку компиляции на kvp.strWord.

error CS1061: 'object' does not contain a definition for 'strWord' and no extension method 'strWord' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)

Если я вставлю следующий код в мой контроллер:

foreach (var kvp in vrGoodResults1)
{
     string strNew = kvp.strWord;
}

Я могу ссылаться на поля моей переменной kvp без ошибки компиляции. Так что что-то теряется при переходе от контроллера к представлению. Я забыл что-то включить? Возможно, в «использовании» или в директиве «<@ Page», я забыл унаследовать что-то? </p>

Когда вы используете LINQ для очистки контекстов данных, вы просто устанавливаете IEnumerable <”datatype”>, где «datatype» = ваш тип контекста данных, и вы все в порядке. Когда вы преобразуете свой набор данных в нечто новое в LINQ, я не могу поверить, что лучшим ответом будет создание нового класса, чтобы я мог использовать его в своем представлении.

Ответы [ 3 ]

3 голосов
/ 09 февраля 2009

var - это ярлык компилятора для объявления типа в текущей области видимости. Он не добавляет никаких динамических функциональных возможностей в среду выполнения .NET, поэтому код вне области видимости рассматривает объект как «System.Object», поскольку это наиболее специфический тип в цепочке наследования, о котором знает код представления.

Вам следует создать реальный класс, если вы хотите передавать объекты кортежей; это то, что вы должны были сделать до var, так что вы не теряете ничего, делая это сейчас:)

2 голосов
/ 09 февраля 2009

Лучший ответ здесь просто - для создания нового типа. Вы можете получить анонимные типы от object ( см. Здесь ), но это уродливо и хрупко Не делай этого!

Вы можете использовать отражение (kvp.GetType().GetProperty("strWord").GetValue(kvp, null)) - но это тоже не очень хорошая идея.

В этом случае - возможно, использовать существующий KeyValuePair<string,int> из исходного выбора? Или свой Tuple<T1,T2>?

0 голосов
/ 09 февраля 2009

Не бойтесь новых типов. Они также дают много других преимуществ, особенно при тестировании. Используйте новый синтаксис свойств, и ваш класс будет иметь столько же строк, сколько у вас есть свойства. Вы можете потерять эту ужасную венгерскую нотацию тоже. Инт и стр - юк

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...