Как справиться с многокритериальными запросами в 3-уровневой архитектуре - PullRequest
4 голосов
/ 30 октября 2009

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

Приложения пользовательского интерфейса состоят из Datagrids с многокритериальными фильтрами, поиск и т. Д.

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

Обратите внимание, что уровень пользовательского интерфейса не знает, как работает DAL.

Ответы [ 7 ]

1 голос
/ 30 октября 2009

Вот для чего DTO .

0 голосов
/ 21 апреля 2011

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

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, чтобы указать, что параметр не требуется.

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

0 голосов
/ 08 ноября 2009

Ознакомьтесь с учебником Роба * . Он использует модель, которая передается из DAL, через уровень Service и даже используется в уровне UI. Это нормально и не нарушает ваших требований, когда пользовательский интерфейс не может знать, как реализован DAL. Вы можете легко переместить свою модель домена в другой проект VS, если вы хотите, чтобы сторонние приложения получили доступ к вашему сервисному уровню и не знали, как работает DAL.

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

0 голосов
/ 08 ноября 2009

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

, например

CustomerDTO example = new CustomerDTO();<br> example.lastName = "jones";<br> AddressDTO exAddr = new AddressDTO();<br> exAddr.city = "Boston";<br> example.addresses.add(exAddr);</p> <p>var customers = svc.GetCustomersLike(example);

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

0 голосов
/ 01 ноября 2009

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

Как это:

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 голосов
/ 31 октября 2009

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

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

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

0 голосов
/ 30 октября 2009

Я использую дозвуковую передачу и передаю коллекцию предложений where методу сервиса

...