簡體   English   中英

CQRS 架構模式中的查詢處理程序

[英]Query handlers in CQRS architectural pattern

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

然后在處理程序中將過濾和排序應用於數據庫中的相應結果這是一個不錯的選擇嗎? 我怎樣才能在我的查詢中實現這種事情? 我的目標是避免為我需要的每個過濾器創建一個查詢,例如“GetParticipantsByNameQuery”、“GetParticipantsByTeamIdQuery”等等

您可以傳入一個過濾器 class ,其中包含過濾結果所需的屬性。

例如:

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

這只是字符串類型的示例,您可以在 switch 塊中添加自己的類型以過濾其他類型。

我接近我的查詢方面的方式如下: -

我有一個代表我的查詢對象的命名空間,以免與我的域發生沖突。

域可能是這樣的:

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

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

讀取的 model看起來像這樣(注意嵌套的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);
    }
}

通過這種方式,您可以將明確的要求傳遞給查詢層,並在需要進一步查詢選項時重構規范 class 和查詢實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM