I completed a CRUD operation with asp for students, then I added an user entity to Student entity. After I added it I had to add some lines in the code in order to work but now I'm stuck at the UPDATE. When I update a student, it's throwing me an error.
This is my update method:
public async Task<Result<Unit>> Handle(Command request, CancellationToken cancellationToken)
{
var student = await _context.Students.FindAsync(request.Student.Id);
if (student == null) return null;
_mapper.Map(request.Student, student);
var result = await _context.SaveChangesAsync() > 0;
if (!result) return Result<Unit>.Failure("Failed to update student");
return Result<Unit>.Success(Unit.Value);
}
The error is thrown at the SaveChangesAsync line, for some reason the AppUser that's an entity at Student table is the cause of it because it works perfectly fine with Students that are not users(when AppUser is null). This is the error that's being thrown:
fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
Failed executing DbCommand (5ms) [Parameters=[@p0='?' (Size = 36), u/p1='?' (DbType = Int32), u/p2='?', u/p3='?' (Size = 36), u/p4='?' (Size = 4), u/p5='?' (Size = 14), u/p6='?' (DbType = Boolean), u/p7='?' (DbType = Boolean), u/p8='?' (DbType = Boolean), u/p9='?' (DbType = DateTimeOffset), u/p10='?' (Size = 14), u/p11='?' (Size = 14), u/p12='?' (Size = 84), u/p13='?', u/p14='?' (DbType = Boolean), u/p15='?' (Size = 32), u/p16='?' (DbType = Boolean), u/p17='?' (Size = 14)], CommandType='Text', CommandTimeout='30']
INSERT INTO "AspNetUsers" ("Id", "AccessFailedCount", "Bio", "ConcurrencyStamp", "DisplayName", "Email", "EmailConfirmed", "IsConfirmed", "LockoutEnabled", "LockoutEnd", "NormalizedEmail", "NormalizedUserName", "PasswordHash", "PhoneNumber", "PhoneNumberConfirmed", "SecurityStamp", "TwoFactorEnabled", "UserName")
VALUES (@p0, u/p1, u/p2, u/p3, u/p4, u/p5, u/p6, u/p7, u/p8, u/p9, u/p10, u/p11, u/p12, u/p13, u/p14, u/p15, u/p16, u/p17);
fail: Microsoft.EntityFrameworkCore.Update[10000]
An exception occurred in the database while saving changes for context type 'Persistence.DataContext'.
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while saving the entity changes. See the inner exception for details.
---> Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 19: 'UNIQUE constraint failed: AspNetUsers.NormalizedUserName'.
at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
The error occurs at normalizedUsername column at AppUsers table but I have no idea why would there be a Constraint at normalizedUsername when I don't even use that column anywhere on code. Can it be because I save the email as the username and maybe the "@gmail.com" is the reason?
And this is my Student:
public class Student
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Email { get; set; }
public string PhoneNumber { get; set; }
public bool IsConfirmed { get; set; }
public string AppUserId { get; set; }
public AppUser AppUser { get; set; }
}
And this is my AppUser:
public class AppUser : IdentityUser
{
public string DisplayName { get; set; }
public string Bio { get; set; }
public bool IsConfirmed { get; set; }
}
CodePudding user response:
I solved it.
The mistake was at the update method, this was my method before I fixed the error:
public async Task<Result<Unit>> Handle(Command request, CancellationToken cancellationToken)
{
var student = await _context.Students.FindAsync(request.Student.Id);
if (student == null) return null;
_mapper.Map(request.Student, student);
var result = await _context.SaveChangesAsync() > 0;
if (!result) return Result<Unit>.Failure("Failed to update student");
return Result<Unit>.Success(Unit.Value);
}
This is it now:
public async Task<Result<Unit>> Handle(Command request, CancellationToken cancellationToken)
{
var student = await _context.Students.Include(x =>
x.AppUser).FirstOrDefaultAsync(x =>x.Id == request.Student.Id);
if (student == null) return null;
_mapper.Map(request.Student, student);
var result = await _context.SaveChangesAsync() > 0;
if (!result) return Result<Unit>.Failure("Failed to update student");
return Result<Unit>.Success(Unit.Value);
}
I wasn't including the AppUser at the student variable, and it threw me an error when I mapped that student with the requested user because it didn't contain the AppUser. When I included the AppUser too, now the SaveChangesAsync is also saving the AppUser and everything works good, for now.