Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用MediatR编辑操作CQRS模式_C#_Asp.net Core_Cqrs_Mediatr - Fatal编程技术网

C# 使用MediatR编辑操作CQRS模式

C# 使用MediatR编辑操作CQRS模式,c#,asp.net-core,cqrs,mediatr,C#,Asp.net Core,Cqrs,Mediatr,我有一个.NETCore3.1MVC应用程序,我正在尝试使用CQRS模式。我是MediatR和CQRS模式的新手 我的命令/查询结构如下: 类别 命令 删除类别 高级类别 询问 GetCategoriesList 类别列表 类别 GetCategoriesListQuery GetCategoriesListQueryHandler 我想使用相同的视图来创建和更新操作,因为我的类别只有两个属性。(其中一个是身份证) My CategoryController.cs文件 [H

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

我的命令/查询结构如下:

  • 类别
    • 命令
      • 删除类别
      • 高级类别
    • 询问
      • GetCategoriesList
        • 类别列表
        • 类别
        • GetCategoriesListQuery
        • GetCategoriesListQueryHandler
我想使用相同的视图来创建和更新操作,因为我的类别只有两个属性。(其中一个是身份证)

My 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);
        }
    }
[HttpGet]
公共IActionResult Upsert(长?id){
if(id==null){
//创建新的,工作正常。
返回视图();
}
//更新现有的不工作。
返回视图(新的UpsertCategoryCommand(){Id=Id});
}
[HttpPost]
[产品响应类型(StatusCodes.Status200OK)]
[ProductsDefaultResponseType]
公共异步任务Upsert(UpsertCategoryCommand命令){
if(ModelState.IsValid){
等待调解人。发送(命令);
返回重定向到操作(名称(索引));
}否则{
返回视图(命令);
}
}
我的类别/索引视图在此处调用upsert方法

<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>

@foreach(Model.Categories中的var项){
@DisplayFor(modelItem=>item.Name)
@ActionLink(“编辑”,“插入”,新建{Id=item.Id})|
@ActionLink(“删除”,“删除”,新的{Id=item.Id})
}
我只想将Id信息发送给控制器,然后发送到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>();
            }
        }
    }
//UpsertCategoryCommand.cs
命名空间…Categorys.Commands.UpsertCategory{
公共类UpsertCategoryCommand:IRequest{
公共long?Id{get;set;}
公共字符串名称{get;set;}
公共类UpsertCategoryCommandHandler:IRequestHandler{
私有只读ITestDbContext\u context;
public UpsertCategoryCommandHandler(ITestDbContext上下文){
_上下文=上下文;
}
公共异步任务句柄(UpsertCategoryCommand请求、CancellationToken CancellationToken){
类别实体;
if(request.Id.HasValue){
entity=wait_context.Categories.FindAsync(request.Id.Value);
}否则{
实体=新类别();
_context.Categories.Add(实体);
}
entity.Name=request.Name;
wait_context.saveChangesSync(cancellationToken);
返回实体Id;
}
}
}
}
//UpsertCategoryCommandValidator.cs
命名空间…Categories.Commands.UpsertCategory{
公共类UpsertCategoryCommandValidator:AbstractValidator{
私有只读ITestDbContext\u context;
公共UpsertCategoryCommandValidator(ITestDbContext上下文){
_上下文=上下文;
RuleFor(x=>x.Name).MaximumLength(100).NotEmpty();
RuleFor(x=>x.Name)
.Must(唯一名称)
.WithMessage(“类别名称必须唯一”);
}
private bool UniqueName(UpsertCategoryCommand类别,字符串名称){
var dbCategory=\u context.Categories
.Where(x=>x.Name.ToLower()==Name.ToLower())
.SingleOrDefault();
if(dbCategory==null)
返回true;
返回dbCategory.Id==category.Id;
}
}
}
//CategoryDto.cs
命名空间…Categories.querys.GetCategoryList{
公共类类别:IMapFrom{
公共长Id{get;set;}
公共字符串名称{get;set;}
公共空白映射(配置文件){
CreateMap();
}
}
}

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

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

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


因此您将拥有CreateCategoryReporte和UpdateCategoryResponse类型。我想吉米在最近的一次谈话中也讨论过这个问题。

我也有同样的问题。我对常见的DTO感到困惑。在我的例子中,类别只有两个属性。如果我创建两个不同的命令,就会有许多重复的代码。若我并没有,我会解决重复代码的问题,但那个是时候,我有一个额外的映射和不必要的若控制命令。所以,我想我会选择重复的代码或者额外的控件。实际上,在很多情况下,重复的代码通常是一件好事。。。。它消除了许多耦合和依赖性。。。每个命令和处理程序应尽可能独立于其他命令/处理程序。是否看到此视频