Prevent duplicate records in ASP.NET Core app with CQRS architecture

52 Views Asked by At

I am implementing a CQRS pattern in ASP.NET Core with MediatR.

I have a model in which I cannot have a unique field under certain conditions, that is, none of its fields can be keyed.

For example, consider the Person model, including name, surname, father's name, age, gender and image.

Now, when add a new record, I have to, check that not registered this information before.

If I want to check the three fields of name, surname and father's name for non-duplication, my request should contain three arguments.

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

Now my question is, do you know a solution for this issue that prevents sending a request with three inputs to the handler, because I read somewhere that writing a action with more than one input violates the clean architecture and is not a clean and principled code at all.

Please advise if you have a solution, thanks

I'm looking for a solution for control adding duplicate record in CQRS pattern, with name, family and father's name fields and not have unique field.

1

There are 1 best solutions below

5
Md Farid Uddin Kiron On

If you could explain with a practical example, I would be grateful. How do I make a combination key?

Well based on your comment, I would try to explain how you could make the composite key. However, its a long implementation, according to the code you have shared is really hard to understand how you are trying so far.

However, for making a composite key, you could combine your domain model properties together in order to search for duplicate entry.

For instance, let's consider, you have following model:

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

So while we would check for duplicate PersonDto object, we will consier that object as duplicate where person's FirstName, LastName and Nickname would be same. Thus, that object would be treated as dulicate entry. This three properties combination called composite key means we are denormalizing the entities in order to search duplication.

Therefore, you should have a method which would take this composite key as the parameter and then search from your database context on the person domain model.

You could implement that in following way:

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

   
}

Finally, you can call above method to check your duplicate personDto Object as following:

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.");
        }

Note: This is one of the approach using composite key you can check for duplicate object. Remember, this only for explaning you how, you could implement that, not the exact solution. In addition, I would recommend you to refer this official document.