如何处理三层体系结构中的多标准查询

时间:2009-10-30 20:46:49

标签: c# architecture 3-tier

假设一个基本的3层应用程序(UI-Service-Data Access),它具有数据访问层的总抽象(SQL,Xml ......)

UI应用程序由带有多标准过滤器的Datagrids组成,查找等。

那么如何在这个体系结构中处理mutli-criteria查询,而不必创建多个服务方法,并将所有可能的标准作为参数......

请注意,UI层不知道DAL的工作原理。

7 个答案:

答案 0 :(得分:1)

这就是DTO的用途。

答案 1 :(得分:0)

我使用亚音速并将where子句的集合传递给服务方法

答案 2 :(得分:0)

我不确定这是否是您正在寻找的,但我使用DAL作为工厂来创建一个DAL感知对象,具有合理的公共属性和/或封装各种过滤条件的方法。 / p>

要求DAL创建对象,根据需要编辑过滤条件,将其退回,并让DAL以对象的任何方式对其给定的访问方法执行此操作。

当然,这假设您没有完全开放式的数据结构......您有一套已知且合理的可能过滤条件。如果它需要灵活到可以传递未知数据结构的仲裁过滤条件,那么这可能不是您的解决方案。

答案 3 :(得分:0)

您可以为要筛选的每个条件创建一个包含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类中添加一个“operator”字段,以允许更多的过滤选项,而不仅仅是完全匹配..

答案 4 :(得分:0)

我喜欢使用Query-By-Example。您可以在此处传递实际示例DTO,并且任何非默认值字段都代表查询条件。

e.g。

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

var customers = svc.GetCustomersLike(example);

这可以从服务层使用,也可以从更高层使用。

答案 5 :(得分:0)

查看Rob的Storefront tutorial。它使用从DAL传递到服务层的模型,甚至在UI层中使用。这没关系,并且不会破坏UI无法知道DAL如何实现的要求。如果您希望第三方应用程序访问您的服务层并且不知道DAL如何工作,您可以轻松地将您的域模型移动到另一个VS项目。

This answer有一些关于如何在更高层中抽象LinqToSql的函数的细节。如果像我一样,你喜欢LinqToSql的延迟执行功能但你不希望你的应用依赖LinqToSql作为数据提供者,你可能想要这样做。

答案 6 :(得分:0)

有多种方法可以做到,我使用了标准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&lt;&gt;对于Value类型,并指定Null以指示不需要该参数。

每种方法都有正面和负面。