使用 CQRS 架构防止 ASP.NET Core 应用程序中的重复记录

问题描述 投票:0回答:1

我正在使用 MediatR 在 ASP.NET Core 中实现 CQRS 模式。

我有一个模型,在某些条件下我不能拥有唯一的字段,也就是说,它的任何字段都不能被键入。

例如,考虑

Person
模型,包括名字、姓氏、父亲的名字、年龄、性别和图像。

现在,当添加新记录时,我必须检查之前是否没有注册过此信息。

如果我想检查名字、姓氏和父亲姓名这三个字段是否不重复,我的请求应该包含三个参数。

namespace HIM_WebApp.Application.Features.Persons.Requests.Queries
{
    public class CheckRepeatedPersonRequest : IRequest<PersonDto>
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Nickname { get; set; }
    }
}

现在我的问题是,您是否知道此问题的解决方案,该解决方案可以防止向处理程序发送具有三个输入的请求,因为我在某处读到,编写具有多个输入的操作违反了干净的架构,并且不是干净且有原则的根本没有代码。

有解决办法请指教,谢谢

我正在寻找一种解决方案,用于控制在 CQRS 模式中添加重复记录,其中包含姓名、家庭和父亲的姓名字段,但没有唯一字段。

asp.net-core duplicates cqrs
1个回答
0
投票

如果您能用实际例子进行解释,我将不胜感激。 如何制作组合键?

根据您的评论,我会尝试解释如何制作复合键。然而,它是一个很长的实现,根据您共享的代码,真的很难理解您到目前为止是如何尝试的。

但是,为了创建复合键,您可以将域模型属性组合在一起以搜索重复条目。

例如,让我们考虑一下,您有以下模型:

public class PersonDto
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Nickname { get; set; }
   
    public string CompositeKey { get; set; } // Denormalized field (FirstName + LastName + Nickname )
}

因此,当我们检查重复的

PersonDto
对象时,我们会将该对象视为重复,其中人的
FirstName
LastName
Nickname
是相同的。因此,该对象将被视为重复条目。这三个属性的组合称为复合键,意味着我们正在对实体进行非规范化以便搜索重复项。

因此,您应该有一个方法,将该组合键作为参数,然后从人员域模型上的数据库上下文中进行搜索。

您可以通过以下方式实现:

public class PersonReadModelRepository : IPersonReadModelRepository
{
    private readonly DbContext _context;

    public PersonReadModelRepository(DbContext context)
    {
        _context = context;
    }

    public async Task<PersonDto> GetByCompositeKeyAsync(string compositeKey)
    {
        var personDto = await _context.Set<PersonDto>()
            .FirstOrDefaultAsync(p => p.CompositeKey == compositeKey);
        return personDto;
    }

   
}

最后,您可以调用上述方法来检查重复的 personDto 对象,如下所示:

var existingPerson = await _readModelRepository.GetByCompositeKeyAsync(person.FirstName + person.LastName + person.Nickname);
        if (existingPerson != null)
        {
            throw new DuplicateRecordException("A person with the same FirstName , LastName , and Nickname name already exists.");
        }

注意:这是使用复合键检查重复对象的方法之一。请记住,这只是为了向您解释如何实现它,而不是确切的解决方案。另外,我建议你参考这个官方文档

© www.soinside.com 2019 - 2024. All rights reserved.