Home > Mobile >  ASP.NET Core Web API - How to resolve The INSERT statement conflicted with the FOREIGN KEY constrain
ASP.NET Core Web API - How to resolve The INSERT statement conflicted with the FOREIGN KEY constrain

Time:08-04

I am implementing Entity Framework in ASP.NET Core-6 Web API and MSSQL DB. I have this code:

Models:

public class BankUser
{
    public Guid { get; set; }
    [ForeignKey("UserId")]
    public string UserId { get; set; }
    public string Description { get; set; }

    [ForeignKey("BankBranchId")]
    public Guid BankBranchId { get; set; }
    public virtual ApplicationUser User { get; set; }
    public virtual BankBranch BankBranch { get; set; }
}

public class BankBranch
{
    public Guid { get; set; }
    public string BranchName { get; set; }
    public virtual BankUser BankUser { get; set; }
}


public class ApplicationUser : IdentityUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public virtual BankUser BankUser { get; set; }
}

BankBranch has many BankUser, while BankUser and Application User is one-to-one.

Configuration:

public class ApplicationUserConfigurations : IEntityTypeConfiguration<ApplicationUser>
{
    public void Configure(EntityTypeBuilder<ApplicationUser> builder)
    {
        builder.Property(u => u.IsDeleted).HasDefaultValue(false);
    }
}

    public void Configure(EntityTypeBuilder<BankBranch> builder)
    {
        builder.ToTable(name: "bank_branches");
        builder.HasKey(b => b.Id);
        builder.Property(b => b.Id).HasDefaultValueSql("NEWID()");
        builder.HasIndex(b => b.BranchName).IsUnique();
        builder.HasIndex(b => b.BranchNumber).IsUnique();
    }
}

public class BankUserConfigurations : IEntityTypeConfiguration<BankUser>
{
    public void Configure(EntityTypeBuilder<BankUser> builder)
    {
        builder.ToTable(name: "bank_users");
        builder.HasKey(b => b.Id);
        builder.Property(b => b.Id).HasDefaultValueSql("NEWID()");
    }
}

Then this is the Dto:

public class BankUserCreateDto
{
    public string UserName { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Role { get; set; }
    public string MobileNumber { get; set; }
    public Guid BankBranchId { get; set; }
}

Finally the implementation:

public async Task<Response<string>> CreateBankUserAsync(BankUserCreateDto model)
{
    var response = new Response<string>();
    using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
    {
            var bankUser = _mapper.Map<ApplicationUser>(model);
            var bankPassword = "@Password*123";
            var result = await _userManager.CreateAsync(bankUser, bankPassword);
            if (result.Succeeded)
            {
                await _userManager.AddToRoleAsync(bankUser, model.Role);
                var user = new BankUser()
                {
                   UserId = bankUser.Id,
                   BankBranchId = model.BankBranchId,
                   Description = model.Description,
                   CreatedBy = _currentUserService.UserName
            };
                await _unitOfWork.AdminUsers.InsertAsync(user);
                await _unitOfWork.Save();

                _logger.Information("Bank User created successfully");
                response.StatusCode = (int)HttpStatusCode.Created;
                response.Successful = true;
                response.Data = _mapper.Map<BankUserDto>(bankUser);
                response.Message = "Bank User created successfully!";
                transaction.Complete();
                return response;
            }

        return response;
    };
}

When I submitted, I got this error:

Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while saving the entity changes. See the inner exception for details. ---> Microsoft.Data.SqlClient.SqlException (0x80131904): The INSERT statement conflicted with the FOREIGN KEY constraint "FK_bank_users_bank_branches_BankBranchId". The conflict occurred in database "ERPs", table "dbo.bank_branches", column 'Id'. The statement has been terminated.

How do I get this sorted out?

Thanks

CodePudding user response:

I think you're having an issue with BankBranch not being populated. If that entity set (table) is empty, then when you're trying to add a BankUser there is no branch to map them to.

Also, you mentioned that BankBranches have many BankUsers. Your code explicitly says in BankBranch:

public virtual BankUser BankUser { get; set; }

This communicates that there is 1 BankUser to the BankBranch. I think you'd rather want:

public virtual IColelction<BankUser> BankUsers { get; set; }

And it seems you're mixing Attributes with FluentAPI. While this can be done, I would suggest trying to stick to one way or the other unless there's a reason not to. Even MS-EF says that attributes can do much of hard work, but FluentAPI is better for your edge cases.

  • Related