ワンクリックで
query-generator
Use when creating a new CQRS query with handler, response DTO, and pagination support.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Use when creating a new CQRS query with handler, response DTO, and pagination support.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Use when adding caching to .NET APIs or optimizing response times with distributed cache, output cache, or ETags.
Use when configuring API response formats, custom formatters, or Accept header handling.
Use when building controller-based REST APIs with action results, model binding, or MediatR integration.
Use when creating RESTful API controllers with MediatR dispatch and ProblemDetails error responses.
Use when designing gRPC services, proto files, or adding gRPC-Web or JSON transcoding.
Use when building minimal API endpoints with route groups, filters, or TypedResults.
| name | query-generator |
| description | Use when creating a new CQRS query with handler, response DTO, and pagination support. |
| metadata | {"category":"cqrs","agent":"ef-specialist","when-to-use":"When generating CQRS query records with handler and response DTO scaffolding"} |
namespace {Company}.{Domain}.Application.Features.Orders.Queries.GetAll;
public sealed record GetOrdersQuery(
int Page = 1,
int PageSize = 20,
string? Search = null,
string? Status = null,
string? SortBy = "CreatedAt",
bool SortDescending = true) : IRequest<Result<PaginatedList<OrderSummaryDto>>>;
namespace {Company}.{Domain}.Application.Features.Orders.Queries.GetAll;
public sealed record OrderSummaryDto(
Guid Id,
string CustomerName,
decimal Total,
string Status,
DateTime CreatedAt);
namespace {Company}.{Domain}.Application.Common;
public sealed class PaginatedList<T>
{
public List<T> Items { get; }
public int TotalCount { get; }
public int Page { get; }
public int PageSize { get; }
public int TotalPages => (int)Math.Ceiling(TotalCount / (double)PageSize);
public bool HasPrevious => Page > 1;
public bool HasNext => Page < TotalPages;
public PaginatedList(List<T> items, int totalCount, int page, int pageSize)
{
Items = items;
TotalCount = totalCount;
Page = page;
PageSize = pageSize;
}
}
namespace {Company}.{Domain}.Application.Features.Orders.Queries.GetAll;
internal sealed class GetOrdersQueryHandler(
IUnitOfWork unitOfWork)
: IRequestHandler<GetOrdersQuery, Result<PaginatedList<OrderSummaryDto>>>
{
public async Task<Result<PaginatedList<OrderSummaryDto>>> Handle(
GetOrdersQuery request, CancellationToken cancellationToken)
{
var query = unitOfWork.Orders.GetQueryable();
// Apply filters
if (!string.IsNullOrEmpty(request.Search))
query = query.Where(o =>
o.CustomerName.Contains(request.Search));
if (!string.IsNullOrEmpty(request.Status))
query = query.Where(o => o.Status == request.Status);
// Apply sorting
query = request.SortBy switch
{
"CustomerName" => request.SortDescending
? query.OrderByDescending(o => o.CustomerName)
: query.OrderBy(o => o.CustomerName),
"Total" => request.SortDescending
? query.OrderByDescending(o => o.Total)
: query.OrderBy(o => o.Total),
_ => request.SortDescending
? query.OrderByDescending(o => o.CreatedAt)
: query.OrderBy(o => o.CreatedAt)
};
var totalCount = await query.CountAsync(cancellationToken);
var items = await query
.Skip((request.Page - 1) * request.PageSize)
.Take(request.PageSize)
.Select(o => new OrderSummaryDto(
o.Id, o.CustomerName, o.Total,
o.Status, o.CreatedAt))
.ToListAsync(cancellationToken);
return Result<PaginatedList<OrderSummaryDto>>.Success(
new PaginatedList<OrderSummaryDto>(
items, totalCount, request.Page, request.PageSize));
}
}
public sealed record GetOrderByIdQuery(Guid Id)
: IRequest<Result<OrderDetailDto>>;
internal sealed class GetOrderByIdQueryHandler(
IUnitOfWork unitOfWork)
: IRequestHandler<GetOrderByIdQuery, Result<OrderDetailDto>>
{
public async Task<Result<OrderDetailDto>> Handle(
GetOrderByIdQuery request, CancellationToken cancellationToken)
{
var order = await unitOfWork.Orders
.GetQueryable()
.Include(o => o.Items)
.Where(o => o.Id == request.Id)
.Select(o => new OrderDetailDto(
o.Id, o.CustomerName, o.Total, o.Status,
o.CreatedAt,
o.Items.Select(i => new OrderItemDto(
i.ProductName, i.Quantity, i.UnitPrice)).ToList()))
.FirstOrDefaultAsync(cancellationToken);
return order is not null
? Result<OrderDetailDto>.Success(order)
: Result<OrderDetailDto>.Failure("Order not found");
}
}
Application/Features/Orders/Queries/
├── GetAll/
│ ├── GetOrdersQuery.cs
│ ├── GetOrdersQueryHandler.cs
│ └── OrderSummaryDto.cs
└── GetById/
├── GetOrderByIdQuery.cs
├── GetOrderByIdQueryHandler.cs
└── OrderDetailDto.cs
| Anti-Pattern | Correct Approach |
|---|---|
| Query modifying data | Queries are read-only |
| Returning domain entities | Project to DTOs with Select |
| Loading full entity graph | Use Select projection |
| No pagination on list queries | Always paginate |
grep -r "IRequest<.*PaginatedList\|IRequest<.*Paginated" --include="*.cs"
grep -r "IRequestHandler.*Query" --include="*.cs"