Когда происходит побежденное казнь? - PullRequest
3 голосов
/ 08 октября 2010

У меня есть ситуация, когда я хочу получить данные из базы данных и назначить их всплывающим подсказкам каждой строки в элементе управления ListView в WPF. (Я использую C # 4.0.) Поскольку я раньше такого не делал, я запустил небольшое, более простое приложение, чтобы изложить идеи до того, как я попытаюсь использовать их в своем основном приложении WPF.

Одной из моих проблем является количество данных, которые потенциально могут быть получены. По этой причине я подумал, что буду использовать LINQ to SQL, который использует отложенное выполнение. Я подумал, что это поможет, а не сбрасывает данные, пока пользователь не наведет указатель мыши на соответствующую строку. Для этого я собираюсь использовать отдельную функцию для присвоения значений подсказке из базы данных, передаваемой по параметрам, которые мне нужно передать соответствующим хранимым процедурам. Я делаю 2 запроса, используя LINQ to SQL, используя 2 разные хранимые процедуры и назначая результаты для 2 разных DataGrids.

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

Если я исключу вызов свойства Count в списке, мне все еще будет интересно, не возникнет ли у меня проблема; Если LINQ все еще может быть вызван, потому что я связываю подсказку с элементом управления через вызов функции?

Ответы [ 3 ]

2 голосов
/ 08 октября 2010

Вы правы, когда вы вызываете свойство Count, оно перебирает набор результатов. По последнему вопросу не ясно, но LINQ, вероятно, вызывается в тот момент, когда вы заполняете свои DataGrids, сразу после появления всплывающей подсказки.

РЕДАКТИРОВАТЬ: однако это не означает, что с отложенным выполнением или использованием вами что-то не так, оно выполняется на самой последней возможной стадии, именно тогда, когда вам нужны данные. Если вы все еще хотите проверить Count перед фактическим извлечением всех данных, вы можете использовать простую функцию LINQ to SQL, которая проверяет строки Any (). (На самом деле Any (), вероятно, то, что вы хотите больше, чем Count> 0)

1 голос
/ 08 октября 2010

Вы должны использовать Any(), а не Count(), но даже Any() вызовет выполнение запроса - в конце концов, он не может определить, есть ли какие-либо строки в наборе результатов без выполнения запрос. Но есть выполнение запроса и получение набора результатов. Any() выберет один ряд, Count() выберет их все.

Тем не менее, я думаю, что не мгновенная операция, которая происходит при наведении мыши, это просто плохая идея. Однажды была сборка Outlook, в которой отображалась полезная подсказка, когда вы наводили курсор на кнопку «Печать». Менее полезно, он получил данные для этой подсказки, вызвав системную функцию, которая выясняет, какие принтеры доступны. Таким образом, вы будете тянуться к меню, и кнопка будет захватывать указатель мыши, и пользовательский интерфейс будет зависать в течение двух секунд, пока он выйдет из строя и выяснит, как отобразить всплывающую подсказку, которую вы даже не просили. Я до сих пор ненавижу эту программу сегодня. Не будь этим парнем.

Лучше было бы асинхронно получать данные всплывающей подсказки после заполнения видимых данных на экране. Достаточно просто создать BackgroundWorker, который извлекает данные в DataTable, а затем сделать DataTable доступным для моделей представлений в обработчике событий RunWorkerCompleted. (Сделайте это там, чтобы не обновлять данные, связанные с пользовательским интерфейсом, в потоке пользовательского интерфейса.) Вы можете реализовать свойство ToolTip в своей модели представления, которое возвращает значение по умолчанию (возможно, нулевое, но, возможно, что-то вроде " Выборка данных ... "), если DataTable, содержащий данные всплывающей подсказки, равен нулю, и это вычисляет значение, если это не так. Это должно работать превосходно. Вы даже можете реализовать уведомление об изменении свойства, чтобы всплывающая подсказка по-прежнему обновлялась, если пользователь удерживает указатель мыши над ним во время извлечения данных.

1 голос
/ 08 октября 2010

Алекс правильно, что вызов Count () или Any () перечислит выражение LINQ, вызывающее выполнение запроса. Я бы порекомендовал переосмыслить ваш дизайн, поскольку вы, вероятно, не хотите, чтобы запрос к базе данных выполнялся каждый раз, когда пользователь перемещает свою мышь. Существует также проблема задержки запроса к базе данных. То, что может быть мгновенным на вашем устройстве разработки с локальной базой данных, может иметь задержку в несколько секунд на сильно загруженном сервере. Я бы порекомендовал создать функцию DisplayTooltip (), которая принимает лениво оцененное выражение LINQ. Затем вы можете кешировать результаты или применить другие эвристические методы, чтобы решить, следует ли вам запрашивать базу данных или нет.

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