gpt4 book ai didi

c# - 使用 MediatR 编辑操作 CQRS 模式

转载 作者:行者123 更新时间:2023-12-05 07:07:31 25 4
gpt4 key购买 nike

我有一个 .Net Core 3.1 MVC 应用程序,我正在尝试使用 CQRS 模式。我是 MediatR 和 CQRS 模式的新手。

我的命令/查询结构是这样的:

enter image description here

  • 类别
    • 命令
      • 删除类别
      • 更新类别
    • 查询
      • 获取类别列表
        • 类别列表Vm
        • 类别Dto
        • 获取类别列表查询
        • GetCategoriesListQueryHandler

我想使用相同的 View 来创建和更新操作,因为我的类别只有两个属性。 (其中一个是Id)

我的 CategoryController.cs 文件

[HttpGet]
public IActionResult Upsert(long? id) {
if (id == null) {
//Create new, working correctly.
return View();
}
//Update existing not working.
return View(new UpsertCategoryCommand() { Id = id });
}

[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesDefaultResponseType]
public async Task<IActionResult> Upsert(UpsertCategoryCommand command) {
if (ModelState.IsValid) {
await Mediator.Send(command);
return RedirectToAction(nameof(Index));
} else {
return View(command);
}
}

我的类别/索引 View 在这里调用更新插入方法。

<tbody>
@foreach (var item in Model.Categories) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.ActionLink("Edit", "Upsert", new { Id = item.Id }) |
@Html.ActionLink("Delete", "Delete", new { Id = item.Id})
</td>
</tr>
}
</tbody>

我只想将 Id 信息发送到 Controller ,然后我如何/在哪里映射/到达 UpsertCategoryCommand。

所有其他型号:

    //UpsertCategoryCommand.cs
namespace ...Categorys.Commands.UpsertCategory {
public class UpsertCategoryCommand : IRequest<long> {
public long? Id { get; set; }

public string Name { get; set; }

public class UpsertCategoryCommandHandler : IRequestHandler<UpsertCategoryCommand, long> {
private readonly ITestDbContext _context;

public UpsertCategoryCommandHandler(ITestDbContext context) {
_context = context;
}

public async Task<long> Handle(UpsertCategoryCommand request, CancellationToken cancellationToken) {
Category entity;

if (request.Id.HasValue) {
entity = await _context.Categories.FindAsync(request.Id.Value);
} else {
entity = new Category();

_context.Categories.Add(entity);
}

entity.Name = request.Name;

await _context.SaveChangesAsync(cancellationToken);

return entity.Id;
}
}
}
}

//UpsertCategoryCommandValidator.cs
namespace ...Categories.Commands.UpsertCategory {
public class UpsertCategoryCommandValidator : AbstractValidator<UpsertCategoryCommand> {
private readonly ITestDbContext _context;

public UpsertCategoryCommandValidator(ITestDbContext context) {
_context = context;

RuleFor(x => x.Name).MaximumLength(100).NotEmpty();
RuleFor(x => x.Name)
.Must(UniqueName)
.WithMessage("Category name must be unique."); ;
}

private bool UniqueName(UpsertCategoryCommand category, string name) {
var dbCategory = _context.Categories
.Where(x => x.Name.ToLower() == name.ToLower())
.SingleOrDefault();

if (dbCategory == null)
return true;

return dbCategory.Id == category.Id;
}
}
}

//CategoryDto.cs
namespace ...Categories.Queries.GetCategoryList {
public class CategoryDto : IMapFrom<Category> {
public long Id { get; set; }

public string Name { get; set; }

public void Mapping(Profile profile) {
profile.CreateMap<Category, CategoryDto>();
}
}
}

创建、编辑和映射同一页面的最佳做法是什么?我可以在命令中使用 CategoryDto 吗?为命令和查询定义任何常见的 Dto,好吗?

最佳答案

我会为 CreateCategory 和 UpdateCategory 创建单独的命令,以便更清楚地了解用户的意图。我还认为这些命令的响应应该是不同的类型,并尽量避免在命令之间重复使用类。

我也只会在每个命令中包含真正必要的字段,而不是尝试在各种命令中重用 CategoryDto。

因此您将拥有 CreateCategoryReponse 和 UpdateCategoryResponse 类型。我还认为吉米在他最近的一次演讲中讨论了这个问题。

关于c# - 使用 MediatR 编辑操作 CQRS 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62112858/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com