如何处理 3 层架构中的多标准查询

发布于 2024-08-09 17:02:00 字数 183 浏览 6 评论 0原文

假设一个基本的 3 层应用程序(UI-服务-数据访问)具有数据访问层的完全抽象(SQL、Xml ...),

UI 应用程序由具有多条件过滤器、查找等的数据网格组成。

那么如何-在此架构中处理多条件查询,而无需创建多个以所有可能条件作为参数的服务方法...

请注意,UI 层不知道 DAL 是如何工作的。

Assuming a basic 3-Tier application (UI-Service-Data Access) with a total abstraction of Data Access layer (SQL, Xml ...)

The UI applications are composed with Datagrids with multi criteria filters, find etc..

So how-to deal with mutli-criteria queries in this architecture without having to create multiple service methods with all possible criteria as parameters...

Note that UI tier doesn't know how the DAL works.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

油饼 2024-08-16 17:02:01

这就是 DTO 的用途。

That is what a DTO is for.

樱娆 2024-08-16 17:02:01

我使用 subsonic 并将一组 where 子句传递给服务方法

I use subsonic and pass a collection of where clauses to the service method

玩套路吗 2024-08-16 17:02:01

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

要求 DAL 创建对象,根据需要编辑过滤条件,将其返回,然后让 DAL 以给定访问方法所需的任何方式处理该对象。

当然,这是假设您没有完全开放的数据结构……您有一组已知且大小合理的可能过滤条件。如果它需要灵活到可以传入未知数据结构的任意过滤条件,那么这可能不是您的解决方案。

I'm not sure if this is what you're looking for, but I use the DAL as a factory to create a DAL-aware object, with reasonable public properties and/or methods that encapsulate the various filter criteria.

Ask the DAL to create the object, edit filter criteria as needed, give it back, and let the DAL do it's thing with the object in whatever way it needs to for its given access method.

This, of course, assumes that you don't have a completely open-ended data structure...that you have a known and reasonable sized set of possible filter criteria. If it needs to be flexible to the point where you can pass in arbitary filter criteria for unknown data structures, this probably isn't your solution.

烟雨扶苏 2024-08-16 17:02:01

您可以创建一个对象,为您要过滤的每个条件保存类似 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”字段,以允许更多的过滤选项,而不仅仅是精确匹配。

You could create an object that holds something like a KeyValuePair for each criteria you want to filter on. Your DAL can then build the where condition from that..

Like this:

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; }
}

You could quite easily extend on that, e.g. add an "operator" field to the FilterCriteria class, to allow for more filtering options than just exact matches..

放肆 2024-08-16 17:02:01

我喜欢为此使用示例查询。您可以在此处传递实际示例 DTO 和任何表示查询条件的非默认值字段。

例如

<代码>
CustomerDTO 示例 = new CustomerDTO();
example.lastName = "琼斯";
AddressDTO exAddr = new AddressDTO();
exAddr.city = "波士顿";
example.addresses.add(exAddr);

varcustomers = svc.GetCustomersLike(example);

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

I like to use Query-By-Example for this. This is where you can pass in an actual example DTO and any non-default-valued fields represent criteria for query.

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);

This could be used from the service layer, or from a higher layer too.

随梦而飞# 2024-08-16 17:02:01

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

这个答案有一些有关在更高层中抽象 LinqToSql 函数的方法的详细信息。如果您像我一样喜欢 LinqToSql 的延迟执行功能,但又不希望您的应用程序依赖 LinqToSql 作为数据提供程序,那么您可能会想要执行此操作。

Check out Rob's Storefront tutorial. It uses a model that is passed up from the DAL, thru the Service layer and even used in the UI layer. This ok, and doesn't break you requirement where the UI can't know how the DAL is implemented. You can easily move your Domain Model onto another VS project in the event you wanted 3rd party apps to access your service layer and not be aware how the DAL works.

This answer has some details about ways to abstract functions of LinqToSql away in higher layers. You might want to do this if, like me, you love the deferred execution features of LinqToSql but you don't want your app to depend on LinqToSql as a data provider.

始终不够爱げ你 2024-08-16 17:02:01

有多种方法可以做到这一点,我使用了条件 API 和查询对象的组合。
例如,如果您有要查询的Persons集合:

1)更灵活的方式条件API:GetPerson(IList query)

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 以指示不需要该参数。

每种方法都有积极的一面和消极的一面。

There are multiple ways to do it, I used mix of criteria API and query objects.
For example if you have Persons collection which you want to query:

1) The more flexible way criteria API: GetPerson(IList query)

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) Strongly described query object:

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

Use Nullable<> for Value types and assign Null to indicate that parameter is not required.

Each method has positive and negative sides.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文