我开始使用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 "等等。
你可以传入一个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));
}
这只是一个字符串类型的例子,你可以在开关块中添加你自己的类型来过滤其他类型。
我在查询方面的方法如下:-----------------------。
为了不与我的域冲突,我有一个命名空间来表示我的查询对象。
域可能是这样的。
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);
}
}
通过这种方式,你有一个明确的需求传递给你的查询层,当你需要进一步的查询选项时,你可以重构你的规范类和查询实现。