2009-10-30 2 views
4

Предполагая базовое 3-уровневое приложение (доступ к данным UI-Service) с общей абстракцией уровня доступа к данным (SQL, Xml ...)Как справиться с многокритериальными запросами в архитектуре с 3 уровнями

приложения UI составлено с DataGrids с мульти критериев фильтрами, найти и т.д ..

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

Обратите внимание, что уровень UI не знает, как работает DAL.

+0

У меня аналогичная проблема –

+0

Вот beggining, но слишком «SQL-зависимые» ... http://www.drewnoakes.com/code/util/Filter.html –

ответ

0

Я использую дозвуковой и передать коллекцию ИНЕК методе обслуживания

+0

Как вы справляетесь с этим? вы передаете SQL where clauses к методу службы? Мой уровень пользовательского интерфейса не знает, как работает DAL, поэтому я не могу передавать простой SQL-код, содержащий предложения по моим методам обслуживания. –

+0

У вас есть доля DAL с клиентом, чтобы заставить это работать. Это не совсем «чистый», но работает очень хорошо. Вы просто должны знать, что вы не можете вызывать методы CRUD от клиента. – ptutt

+0

@ptutt Нет, я не могу поделиться DAL с клиентом. Я думаю, что это не большой дизайн архитектуры. Клиент только разговаривает с уровнем обслуживания (бизнес) –

0

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

Попросите DAL создать объект, отредактировать критерии фильтра по мере необходимости, вернуть его и позволить DAL делать это с объектом любым способом, которым он должен обладать для данного метода доступа.

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

+0

@Beska Мне нужен общий и абстрактный способ обработки нескольких запросов критериев. Но не специфика методов, как это: общественного IList FindSomething (интермедиат filter1, строка filter2 ...) Но, может быть, более гибкий способ с LINQ выражения, как: общественного IList Find (Expression фильтры []) Не знаю ... –

0

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

Как это:

class MultiCriteriaFiltering 
{ 
    List<FilterCriteria> Criterias; 

    // this method just sits here for simplicity - it should be in your DAL, not the DTO 
    string BuildWhereCondition() 
    { 
     StringBuilder condition = new StringBuilder(); 
     condition.Append("WHERE (1=1) " 
     foreach (FilterCriteria criteria in Criterias) 
     { 
      condition.Append(" AND ").Append(criteria.FieldName).Append(" = "); 
      condition.Append("'").Append(criteria.FilterValue).Append("'"); 
     } 
     return condition.ToString(); 
    } 
} 

class FilterCriteria 
{ 
    string FieldName { get; set; } 
    object FilterValue { get; set; } 
} 

Вы можете довольно легко расширить на том, что, например, добавьте поле «оператор» в класс FilterCriteria, чтобы разрешить больше параметров фильтрации, чем просто точные совпадения.

0

Мне нравится использовать Query-By-Example для этого. Здесь вы можете передать фактический пример DTO, и любые поля, не относящиеся к по умолчанию, представляют критерии запроса.

например.

CustomerDTO example = new CustomerDTO();
example.lastName = "jones";
AddressDTO exAddr = new AddressDTO();
exAddr.city = "Boston";
example.addresses.add(exAddr);

var customers = svc.GetCustomersLike(example);

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

0

Отъезд Rob's Storefront tutorial. Он использует модель, которая передается из DAL, через уровень сервиса и даже используется в слое пользовательского интерфейса. Это нормально и не нарушает требования, когда пользовательский интерфейс не может знать, как реализуется DAL. Вы можете легко перенести свою модель домена на другой проект VS, если вы хотите, чтобы сторонние приложения получали доступ к вашему уровню обслуживания и не знали, как работает DAL.

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

0

Существует несколько способов сделать это, я использовал сочетание критериев API и объектов запроса. Например, если у вас есть коллекция лиц, которые вы хотите запросить:

1) Более гибкие критерии путь API: GetPerson (IList запрос)

public class Criteria 
{ 
Object Property; // (Domain property, not DB)// (String Or Lambda) Age, Father.Age, Friends, etc 
Object Operator; //(Enum or String)(Eq, Gr, Between,Contains, StartWith, Whatever...) 
Object Value; // (most likely Object, or use generics Criteria<T>), (Guid, int[], Person, any type). 
} 

2) Сильно описываемый объект запроса:

public class PersonQuery 
{ 
Guid? Id; 
GenderEnum? Gender; 
Int32? Age; 
Int32? AgeMin; 
Int32? AgeMax; 
String Name; 
String NameContains; 
Person FatherIs; 
Person MotherIs; 
//... 
} 

Используйте Nullable <> для типов значений и назначьте Null, чтобы указать, что параметр не требуется.

Каждый метод имеет положительные и отрицательные стороны.