Одесса: 9°С (вода 9°С)
Киев: 2°С
Львов: 5°С

Тема: Проблема ASP.NET и LINQ

Ответить в теме
Показано с 1 по 8 из 8
  1. Вверх #1
    Новичок
    Пол
    Мужской
    Возраст
    33
    Сообщений
    39
    Репутация
    15

    По умолчанию Проблема ASP.NET и LINQ

    Поставлена тривиальная задача: отобразить список вопросов в виде таблицы с возможностью изменения позиции вопроса. Единственное требование использование GridView + Linq. Итак имеем: таблица со структурой ID (Pimary Key), Text, Position; GridView и LinqDataSource. В GridView создаем поля: BoundField к Position, BoundField к Text и два ButtonField с командами MoveUp и MoveDown. В обработчике OnRowCommand имеем такой код:
    ...
    if (e.CommandName == "MoveUp")
    {
    int index = Convert.ToInt32(e.CommandArgument);
    GridViewRow row = gridView.Rows[index];
    byte currentPostion = Convert.ToByte(row.Cells[0].Text);

    if (currentPostion > 1)
    {
    DataContext db = new DataContext();
    Question qPrev = (from q in db.Questions where q.Position == (currentPostion-1) select q).FirstOrDefault();
    Question qNew = (from q in db.Questions where q.Position == currentPostion select q).FirstOrDefault();
    qNew.OrdinalPosition = (byte)(currentPostion - 1);
    qPrev.OrdinalPosition = currentPostion;
    db.SubmitChanges();

    gridView.DataBind();
    }
    }
    ...

    Для команды MoveDown код аналогичный. Таблица заполнена правильно, т.е. у всех записей позиция отличается на 1, и минимальная позиция равна 1. В Опере и ФФ это все работает отлично, но в ИЕ8 (как в принципе и в ИЕ7) все время получаю ошибки
    либо на строке
    "Question qPrev = (from q in db.Questions where q.Position == (currentPostion-1) select q).FirstOrDefault();" получаю ошибку, что запись не найдена, либо на строке "db.SubmitChanges();" ошибку "Row not found or changed.". Хотя я уверен, что эти записи есть 100%. Вот и возник вопрос почему в Опере и ФФ это работет безотказно, а в ИЕ не хочет? И как это побороть?


  2. Вверх #2
    Новичок Аватар для сохен самуй
    Пол
    Мужской
    Адрес
    там - тут
    Возраст
    34
    Сообщений
    48
    Репутация
    20
    Вообще-то сам код обрабатывается на сервере
    к браузеру отношение не имеет, можете зайти дебагером и глянуть правильно выполнятся ли код на стороне сервера.

    Если проблема отображения в браузерах, то Вам надо смотреть сторону клиента тоесть как делается вывод в браузер - непосредственно хтмл код ...
    Последний раз редактировалось сохен самуй; 10.10.2009 в 16:53.

  3. Вверх #3
    Новичок
    Пол
    Мужской
    Возраст
    33
    Сообщений
    39
    Репутация
    15
    Да, я прекрасно понимаю, что серверный код никак не зависит от браузера клиента. Но вот сложилась такая ситуация, что хтмл код одинаков (серверный естественно тоже) для разных браузеров, а вот в одних оно работает, а в других не хочет.

  4. Вверх #4
    Цитата Сообщение от el_Wild Посмотреть сообщение
    ...а в других не хочет.
    в другом

  5. Вверх #5
    Новичок Аватар для BloodAxe
    Пол
    Мужской
    Адрес
    Одесса
    Возраст
    31
    Сообщений
    82
    Репутация
    36
    Попробуйте пройтись отладчиком по функции пошагово.
    В первую очередь в строке:
    >int index = Convert.ToInt32(e.CommandArgument);
    Убедитесь, что в параметре e.CommandArgument передаются правильные данные.

    PS: Мой вам совет - привязывайте CommandArgument не к полю Position, а к PK строки.
    У вас изменятся, соответственно, запросы, но такое решение более правильное. Несгласное соглашение о том, что номера позиций вопросов должны отличаться не более чем на 1 очень негибко.

  6. Вверх #6
    А для GridView в свойстве DataKeyNames указано ключевое поле? Типовое решение - это добавление невидимой колонки, привязанной к PK таблицы, и указании ее в качестве ключевой для грида.
    Кроме того, зачем для каждой записи рендерить кнопки MoveUp и MoveDown? Не проще ли разместить их рядом с гридом и менять положение выделенной записи (записей)?

  7. Вверх #7
    Новичок
    Пол
    Мужской
    Возраст
    33
    Сообщений
    39
    Репутация
    15
    Спасибо всем за помощь. Итак по порядку.

    Попробуйте пройтись отладчиком по функции пошагово.
    В первую очередь в строке:
    >int index = Convert.ToInt32(e.CommandArgument);
    Убедитесь, что в параметре e.CommandArgument передаются правильные данные.
    В e.CommandArgument передаются правильные данные. К сожалению отладчиком воспользоваться не могу, возникают ошибки доступа к файлам базы данных (ну это уже особенности моей системы), поэтому приходится пользоваться доступными методами вывода через Response и запись в файл.

    PS: Мой вам совет - привязывайте CommandArgument не к полю Position, а к PK строки.
    У вас изменятся, соответственно, запросы, но такое решение более правильное. Несгласное соглашение о том, что номера позиций вопросов должны отличаться не более чем на 1 очень негибко.
    Я бы не сказал, что это негласное соглашение. Просто создать запись с позицией отличающейся не на 1 от соседних через интерфейс не получится. Если же позиции будут отличаться не на 1, то задача перестановки местами строк усложняется. Но про привязку к РК строки полностью согласен.

    А для GridView в свойстве DataKeyNames указано ключевое поле? Типовое решение - это добавление невидимой колонки, привязанной к PK таблицы, и указании ее в качестве ключевой для грида.
    Кроме того, зачем для каждой записи рендерить кнопки MoveUp и MoveDown? Не проще ли разместить их рядом с гридом и менять положение выделенной записи (записей)?
    Да, для GridView указано ключевое поле. Рендерить кнопки для каждой записи все же проще, чем размещать их рядом с гридом и работать с выделенной записью. Насколько это правильней вопрос личных предпочтений. К тому же в моем случае этот вопрос решаю не я, а заказчик с дизайнером. Так что тут вариантов не оставалось.

    В любом случае задача решена. Проблема была в том что при использовании ButtonField в GridView событие RowCommand срабатывает дважды (это вроде как баг стандартного GridView). Решение: использовать TemplateField с кнопками внутри вместо ButtonField.
    Измененный код теперь выглядит примерно так:
    ...
    int QuestionID = Convert.ToInt32(e.CommandArgument);
    DataContext db = new DataContext();
    Question qCurrent = (from q in db.Questions where q.ID == QuestionID select q).FirstOrDefault();
    if (e.CommandName == "MoveUp")
    {
    if ((qCurrent != null) && (qCurrent.Position > 1))
    {
    Question qPrev = (from q in db.Questions
    where q.Position == (qCurrent.Position-1)
    select q).FirstOrDefault();

    if (qPrev != null)
    {
    qPrev.Position = qCurrent.Position;
    qCurrent.Position--;

    try
    {
    db.SubmitChanges();
    }
    catch (System.Data.Linq.ChangeConflictException ex)
    {
    db.SubmitChanges();
    }

    gridViewQuestions.DataBind();
    }
    }
    }
    ...
    Последний раз редактировалось el_Wild; 12.10.2009 в 11:35.

  8. Вверх #8
    Новичок
    Пол
    Мужской
    Возраст
    33
    Сообщений
    39
    Репутация
    15
    Столько времени решение заняло всего лишь из-за невозможности воспользоваться нормально отладчиком и обнаружить двойное событие. Ну и из-за особенностей ИЕ при передаче данных.


Ответить в теме

Похожие темы

  1. Требуется ASP.NET разработчик
    от Webidea в разделе Предлагаю работу
    Ответов: 3
    Последнее сообщение: 04.09.2012, 10:04
  2. ASP.NET Вакансии
    от eodessa в разделе Предлагаю работу
    Ответов: 1
    Последнее сообщение: 31.05.2012, 06:58
  3. Сайт на ASP.NET 2.0
    от Михаилл1 в разделе Интернет :: технические вопросы
    Ответов: 0
    Последнее сообщение: 19.08.2011, 12:53

Социальные закладки

Социальные закладки

Ваши права

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