CQRS架构模式中的查询处理程序

问题描述 投票:-1回答:2

我开始使用CQRS,我想我不太确定如何(或者是否可以这样做)添加一个查询,可以对最终查询的结果进行过滤和排序,例如。

public partial class GetParticipantListQuery : IRequest<IList<ParticipantDto>>
{
    public Expression<Func<ParticipantDto, bool>> Filter { get; set; } = null;
    public Func<IQueryable<ParticipantDto>, IQueryable<ParticipantDto>> OrderBy { get; set; } = null;
}

然后在处理程序中对来自DBIs的相应结果进行过滤和排序 这是个好的选择吗?我如何在我的查询中实现这种事情?我的目标是避免为我需要的每个过滤器创建一个查询,比如 "GetParticipantsByNameQuery","GetParticipantsByTeamIdQuery "等等。

c# .net-core entity-framework-core domain-driven-design cqrs
2个回答
1
投票

你可以传入一个filter类,它包含了过滤结果的必要属性。

例如:public partial ...你可以传入一个过滤器类,它包含了过滤结果所需的属性。

public class Filter
{
    //Property Name
    public string Key { get; set; }
    //Property Type eg. string, int, bool
    public string Type { get; set; }
    //Value to filter
    public object Value { get; set; }
}

var result = from u in _context.Set<T>() select u;
switch(filter.Type)
{
    case "string":
        result = result.Where(e => EF.Property<string>(e, filter.Key).Equals((string)filter.Value));
}

这只是一个字符串类型的例子,你可以在开关块中添加你自己的类型来过滤其他类型。


1
投票

我在查询方面的方法如下:-----------------------。

为了不与我的域冲突,我有一个命名空间来表示我的查询对象。

域可能是这样的。

namespace Product
{
    public class Order
    {
        public Guid Id { get; }
        public DateTime RegisteredDate { get; }

        public Order(Guid id, DateTime registeredDate)
        {
            Id = id;
            RegisteredDate = registeredDate;
        }
    }
}

域可能是这样的: 读取模型 将看起来像这样(注意嵌套的 Specification 类)。)

namespace Product.DataAccess.Query
{
    public class Order
    {
        public class Specification
        {
            public Guid? Id { get; private set; }
            public DateTime? RegisteredDateStart { get; private set; }
            public DateTime? RegisteredDateEnd { get; private set; }

            public Specification WithId(Guid id)
            {
                Id = id;

                return this;
            }

            public Specification WithRegisteredDateStart(DateTime registeredDateStart)
            {
                RegisteredDateStart = registeredDateStart;

                return this;
            }

            public Specification WithRegisteredDateEnd(DateTime registeredDateEnd)
            {
                RegisteredDateEnd = registeredDateEnd;

                return this;
            }
        }

        public Guid Id { get; set; }
        public DateTime RegisteredDate { get; set; }
    }
}

在我的查询层中,我把规范传递过来,然后查询层可以使用规范值来构造查询。

namespace Product.DataAccess
{
    public interface IOrderQuery
    {
        IEnumerable<Query.Order> Search(Query.Order.Specification specification);
        int Count(Query.Order.Specification specification);
    }
}

通过这种方式,你有一个明确的需求传递给你的查询层,当你需要进一步的查询选项时,你可以重构你的规范类和查询实现。

© www.soinside.com 2019 - 2024. All rights reserved.