Какой шаблон проектирования следует использовать для создания простой карты привязки между запросом и текстовыми полями для экранов поиска Linq? - PullRequest
2 голосов
/ 13 мая 2009

Снова и снова я занимаюсь разработкой экранов бизнес-приложений WinForm, в которых есть несколько текстовых полей для критериев поиска, а затем кнопка поиска. Они отображаются в выражение с помощью Linq, а затем передаются на мой слой Linq2Sql.

Я хотел бы создать простой способ «привязать» эти текстовые поля к базовому запросу, используя различные параметры, такие как «contains», «setswith», «точный совпадение» и т. Д. ...

Я представляю себе что-то вроде этого (обратите внимание, что SearchBinderT воображаем):

SearchBinder<Customer> searchBinder = new SearchBinder<Customer>();
searchBinder.Bind(txtFirstName, a=>a.FirstName, SearchBinderOptions.StarsWith);
searchBinder.Bind(txtLastName, a=>a.LastName, SearchBinderOptions.StarsWith);
searchBinder.Bind(txtTelephone, a=>a.Phone, SearchBinderOptions.Equals);
searchBinder.SetAction(btnSearch, MyMethodThatHandlesTheExpressionTreeAndFillsTheResults);

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

  • Какой шаблон (ы) дизайна вы бы использовали для этого (или я думаю, что это хорошо)?
  • Как бы вы работали с другими типами данных (даты / числа с числом меньше или больше)

1 Ответ

0 голосов
/ 13 мая 2009

Не решит ли это отложенное выполнение и захваченное состояние лямбд?

Predicate<Customer> searchQuery = c => {
   c.FirstName.StartsWith(txtFirstName.Text)
   && c.LastName.StartsWith(txtLastName.Text)
   && c.Phone == txtTelephone.Text;
}

void btnSearch_Click(object sender, EventArgs e) {
    return IEnumerable<Customer>.Where(searchQuery);
}

Поскольку searchQuery не выполняется до нажатия кнопки, нет необходимости абстрагироваться от сравнений с компонентами «компоновщика». Существует целая многопоточная проблема с доступом к текстовым полям, но вы могли бы вместо этого использовать Expression<T> и разложить и перестроить с помощью Control.Invoke. Или просто запишите его с Invoke для начала. Или отправьте его обратно в поток пользовательского интерфейса для запуска.

Но, если вы действительно хотите использовать свой дизайн - я бы предложил использовать Expression<T> вместо операторов сравнения, которые у вас есть. Он более гибкий и сэкономит вам немало работы.

Что касается шаблона проектирования, то самым близким из известных мне будет Объект запроса , который [N] Hibernate имеет в виде Критерии . Это больше касается построения динамических запросов, но не привязки к элементам пользовательского интерфейса (что, опять же, я не вижу смысла). В вашем примере ваш запрос жестко запрограммирован, поэтому я не уверен, какая выгода будет.

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