После обновления до .NET 8.0 я получаю EntityFrameworkCore.DbUpdateException: «Не удалось сохранить изменения, посколькуC#

Место общения программистов C#
Ответить
Anonymous
 После обновления до .NET 8.0 я получаю EntityFrameworkCore.DbUpdateException: «Не удалось сохранить изменения, поскольку

Сообщение Anonymous »

Я обновил свой веб-API ASP.NET Core 6 до .NET 8.0.
На странице входа у меня есть следующий код:
public async Task LoginAttempt([Bind("Email","Password","PingIdPin","SelectDeviceMessage","SelectDevice","CollectPinMessage","CollectPin","MultipleDevices","MultipleDevicesYesNo","ChallengeId","UserPrompt","LoginFailed")] LoginModel loginModel)
{
// more snippets of the code
Microsoft.AspNetCore.Identity.SignInResult result = new();

try
{
result = await _signInManager.PasswordSignInAsync(user, password, false, false);
}
catch (Exception ex)
{
string ss = ex.Message;
_logger.LogInformation(-999000001, "{0} ... result = await _signInManager.PasswordSignInAsync(user, password, false, false); [{1}]", nameof(Login), ex.Message);
}
}

Я получаю следующее исключение:

EntityFrameworkCore.DbUpdateException: Microsoft.EntityFrameworkCore.DbUpdateException: 'Не удалось сохранить изменения, поскольку в целевой таблице есть триггеры базы данных. Пожалуйста, настройте свою таблицу соответствующим образом, см. https://aka.ms/efcore-docs-sqlserver-sa ... put-clause для получения дополнительной информации».
SqlException: целевая таблица «AspNetUsers» оператора DML не может иметь включенных триггеров, если оператор содержит предложение OUTPUT без предложения INTO.

Я обновил все пакеты Nuget до 8.0.8 для Entity Framework Core.
См. снимок экрана с NugetPackages для 8.0.
С .NET 6.0 все работало без проблем. Не знаю, чего мне не хватает при обновлении до .NET 8.0.
Мой код DBcontext.cs:
namespace AspNetCoreApi.Models.Identity
{
public class AppIdentityDbContext : IdentityDbContext
{
public AppIdentityDbContext() { }

public static string ConnectionString { get; set; }
public static int MessageMaxLength;

public AppIdentityDbContext(DbContextOptions options)
: base(options) { }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(ConnectionString);
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity().ToTable(tb => tb.HasTrigger("TriggerName"));

base.OnModelCreating(modelBuilder);
modelBuilder.Entity(entity =>
{
entity.ToTable(
"AspNetUsers");

entity.HasKey(x => x.Id);
entity.HasIndex(e => e.NormalizedEmail)
.HasDatabaseName("EmailIndex");

entity.HasIndex(e => e.NormalizedUserName)
.HasDatabaseName("UserNameIndex")
.IsUnique()
.HasFilter("([NormalizedUserName] IS NOT NULL)");

entity.Property(e => e.CreatedBy).HasMaxLength(50);

entity.Property(e => e.Email).HasMaxLength(128);

entity.Property(e => e.Facility).HasMaxLength(50);

entity.Property(e => e.FirstName).HasMaxLength(50);

entity.Property(e => e.LastName).HasMaxLength(50);

entity.Property(e => e.Name).HasMaxLength(128);

entity.Property(e => e.NormalizedEmail).HasMaxLength(128);

entity.Property(e => e.NormalizedUserName).HasMaxLength(128);

entity.Property(e => e.PhoneNumber).HasMaxLength(50);

entity.Property(e => e.UpdatedBy).HasMaxLength(50);

entity.Property(e => e.UserName).HasMaxLength(50);

entity
.HasMany(e => e.Claims)
.WithOne()
.HasForeignKey(e => e.UserId);

entity
.HasMany(e => e.Tokens)
.WithOne()
.HasForeignKey(e => e.UserId);

entity
.HasMany(e => e.Logins)
.WithOne()
.HasForeignKey(e => e.UserId);

entity
.HasMany(e => e.Roles)
.WithOne()
.HasForeignKey(e => e.UserId);

});
}
}

После добавления строки «HasTrigger» ошибка не отображается, но ничего не происходит и приложение останавливается. Что я здесь делаю не так?
Ниже мой сгенерированный SQL:
public async Task SaveUser(UserVM model, string thisUser)
{
bool hasErrors = false;
int retUserId = 0;

if (model.Id > 0)
{
AspNetUsers user = await (from u in _context.AspNetUsers
where u.Id == model.Id
select u).FirstOrDefaultAsync();

user.Email = model.Email;
user.NormalizedEmail = model.Email.ToUpper();
user.FirstName = model.FirstName;
user.MiddleName = model.MiddleName;
user.LastName = model.LastName;
user.Inactive = !model.Active;
user.UserName = model.UserName;
user.NormalizedUserName = model.UserName.ToUpper();
user.Name = model.UserName;
user.UpdateDate = DateTime.Now;
user.UpdatedBy = thisUser;

_context.AspNetUsers.Update(user);
await _context.SaveChangesAsync();

AspNetUserClaims claimLname = await (from c in _context.AspNetUserClaims
where c.UserId == user.Id
&& c.ClaimType == "Surname"
select c).FirstOrDefaultAsync();

if (claimLname != null)
{
if (claimLname.ClaimValue != user.LastName)
{
claimLname.ClaimValue = user.LastName;
_context.AspNetUserClaims.Update(claimLname);
await _context.SaveChangesAsync();
}
}

AspNetUserClaims claimFname = await (from c in _context.AspNetUserClaims
where c.UserId == user.Id
&& c.ClaimType == "GivenName"
select c).FirstOrDefaultAsync();

if (claimLname != null)
{
if (claimLname.ClaimValue != user.LastName)
{
claimFname.ClaimValue = user.FirstName;
_context.AspNetUserClaims.Update(claimFname);
await _context.SaveChangesAsync();
}
}

if (hasErrors == false)
{
var deleteRoles = await (
//_context.AspNetRoles.Where(x => EF.Property(x, "UserId") == user.Id).ToListAsync());
_context.AspNetUserRoles.Where(x => x.UserId == user.Id).ToListAsync());

foreach (var i in deleteRoles)
{
_context.AspNetUserRoles.Remove(i);
try
{
await _context.SaveChangesAsync();
}
catch (Exception ex)
{
string s = ex.Message;
}
}

// remove claim for Role
var userClaimRoles = await _context.AspNetUserClaims
.Where(x => x.UserId == user.Id && x.ClaimType == "Role")
.ToListAsync();

foreach (AspNetUserClaims claim in userClaimRoles)
{
_context.AspNetUserClaims.Remove(claim);
}

// remove claim for Name Identifier
userClaimRoles = await _context.AspNetUserClaims
.Where(x => x.UserId == user.Id && x.ClaimType == "NameIdentifier")
.ToListAsync();

foreach (AspNetUserClaims claim in userClaimRoles)
{
_context.AspNetUserClaims.Remove(claim);
}

await _context.SaveChangesAsync();

string roleName = await (from r in _context.AspNetRoles
where r.Id == model.RoleId
select r.RoleName).FirstOrDefaultAsync();

var entity = await _userManager.FindByEmailAsync(user.Email);

if (entity != null)
{
if (!string.IsNullOrEmpty(roleName))
{
await _userManager.AddToRoleAsync(entity, roleName);
await _userManager.AddClaimAsync(entity, new Claim("Role", roleName));
}

await _userManager.AddClaimAsync(entity, new Claim("NameIdentifier", user.UserName));

await _context.SaveChangesAsync();
}

// set if no errors otherwise return 0 which is error in page
retUserId = user.Id;
}
}
else
{
int newUserId = 0;

ApplicationUser entity = new ApplicationUser
{
Id = model.Id,
Email = model.Email,
UserName = model.UserName,
FirstName = model.FirstName,
MiddleName = model.MiddleName,
LastName = model.LastName,
Name = model.UserName,
NormalizedUserName = model.UserName.ToUpper(),
NormalizedEmail = model.Email.ToUpper(),
CreateDate = DateTime.Now,
CreatedBy = thisUser,
UpdateDate = DateTime.Now,
UpdatedBy = thisUser,
Inactive = !model.Active,
SecurityStamp = Guid.NewGuid().ToString()
};

IdentityResult result
= await _userManager.CreateAsync(entity, model.Password);

if (result.Succeeded)
{
newUserId = entity.Id;

await _userManager.AddClaimAsync(entity, new Claim("GivenName", entity.FirstName));
await _userManager.AddClaimAsync(entity, new Claim("Surname", entity.LastName));
await _userManager.AddClaimAsync(entity, new Claim("NameIdentifier", entity.UserName));

string roleName = await (from r in _context.AspNetRoles
where r.Id == model.RoleId
select r.RoleName).FirstOrDefaultAsync();
await _userManager.AddToRoleAsync(entity, roleName);
await _userManager.AddClaimAsync(entity, new Claim("Role", roleName));
await _context.SaveChangesAsync();

retUserId = newUserId;
}
else
{
foreach (IdentityError err in result.Errors)
{
_logger.LogError(3, "userId: " + newUserId.ToString() + " " + err.Code + " - " + err.Description);
}
}
}

return retUserId;
}


Подробнее здесь: https://stackoverflow.com/questions/789 ... xception-c
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»