我正在使用Asp .Net Core Razor页面,并使用CRUD搭建了模型,并为我生成了用于创建,编辑,删除等的页面...
问题是,除编辑外,所有其他功能均有效。
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(Utilizador).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!UtilizadorExists(Utilizador.UserID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
每当点击保存更改时,都会给出尝试插入的异常
SqlException:无法在对象中插入重复的键行 具有唯一索引“ IX_xColaboradores_UserID”的“ dbo.xColaboradores”。的 重复键值为(8)。该声明已终止。
这是模型
public class Colaborador
{
[Key]
[ForeignKey("Utilizador")]
public int ColaboradorID { get; set; }
public string Nome { get; set; }
public string Email { get; set; }
public int UserID { get; set; }
public virtual Utilizador Utilizador { get; set; }
public int DepartamentoID { get; set; }
public virtual Departamento Departamento { get; set; }
}
public class Utilizador
{
[Key]
[ForeignKey("Colaborador")]
public int UserID { get; set; }
public string Username { get; set; }
public bool IsActivo { get; set; }
public DateTime? UltimoAcesso { get; set; }
public virtual Colaborador Colaborador { get; set; }
}
我尝试附加相关实体,但又给出了另一个例外
InvalidOperationException:实体类型上的属性'ColaboradorID' “ Colaborador”在尝试更改 实体的状态为“不变”。要么显式设置一个永久值 或确保将数据库配置为为此生成值 属性。
编辑
我仍然不确定这在实体框架上如何工作,但是似乎它直接从绑定的页面获取对象。
我注意到某些属性没有值,例如相关实体的ID。它们为0,因此为什么要插入。为了解决这个问题,我不得不将主ID和外ID放在隐藏的输入中,否则它将尝试插入它们并给出重复的异常
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Utilizador.UserID" />
<input type="hidden" asp-for="Utilizador.Colaborador.ColaboradorID" />
<input type="hidden" asp-for="Utilizador.Colaborador.UserID" />
<div class="form-group">
<label asp-for="Utilizador.Username" class="control-label"></label>
<strong class="text-danger">*</strong>
<input asp-for="Utilizador.Username" class="form-control form-control-sm" />
<span asp-validation-for="Utilizador.Username" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Utilizador.Colaborador.Nome" class="control-label"></label>
<strong class="text-danger">*</strong>
<input asp-for="Utilizador.Colaborador.Nome" class="form-control form-control-sm" />
<span asp-validation-for="Utilizador.Colaborador.Nome" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Utilizador.Colaborador.Email" class="control-label"></label>
<strong class="text-danger">*</strong>
<input asp-for="Utilizador.Colaborador.Email" class="form-control form-control-sm" />
<span asp-validation-for="Utilizador.Colaborador.Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Utilizador.Colaborador.Departamento.Designacao" class="control-label"></label>
<strong class="text-danger">*</strong>
<select asp-for="Utilizador.Colaborador.DepartamentoID" asp-items="Model.DepartamentosList" class="form-control form-control-sm">
<option value="">Selecione um departamento</option>
</select>
<span asp-validation-for="Utilizador.Colaborador.DepartamentoID" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Guardar" class="btn btn-block text-white text-uppercase text-bold" style="background-color:#124475; box-shadow:0 5px 5px 0 rgba(0, 0, 0, 0.2), 0 8px 5px 0 rgba(0, 0, 0, 0.19);" />
</div>
</form>
和后端
_context.Attach(Utilizador).State = EntityState.Modified;
_context.Attach(Utilizador.Colaborador).State = EntityState.Modified;
与此同时,我可以更改相关实体,并且可以正常更新。
不确定这是否是最佳实践,因为我尝试使用开发工具在浏览器上更改值,并且可以很容易地将其黑客化,或者是否存在另一种获取这些值而不将其存储在隐藏的输入中的方法,但我注意到生成的值脚手架项目页面已经在隐藏的输入中存储了主键ID。