如何防止ASP.NET Core w/ EF中创建/编辑功能的重复条目?

brgchamk  于 2022-11-19  发布在  .NET
关注(0)|答案(1)|浏览(111)

我试图阻止用户创建一个带有FirstName、LastName和DOB的表单,这些表单与数据库中的条目相匹配,并编辑一个表单以匹配现有的条目。如果您也能告诉我,在发生这种情况时,我如何显示错误,那就太棒了。
我的模型:

public class MRegForm
{
    public int MRegFormId { get; set; }
    [Display(Name = "First Name")]
    public string FirstName { get; set; } = string.Empty;
    [Display(Name = "Last Name")]
    public string LastName { get; set; } = string.Empty;
    public DateTime DOB { get; set; }

[我尝试了索引属性。它对我不起作用。我能够创建新的重复表单,没有任何问题。

[Index(nameof(FirstName), nameof(LastName), nameof(DOB), IsUnique = true)]
public class MRegForm
{

我也试过这个。一样的。

protected override void OnModelCreating(ModelBuilder modelbuilder)
    {
        base.OnModelCreating(modelbuilder);

        modelbuilder.Entity<MRegForm>()
            .HasIndex(x => new { x.FirstName, x.LastName, x.DOB})
            .IsUnique();

    }

    public DbSet<MRegForm> MRegForm { get; set; } = default!;

我认为在OnPostAsync()中可能有一种方法可以防止这种情况
这是我创建的OnPostAsync():

public async Task<IActionResult> OnPostAsync()
    {
        MRegForm.CreatorId = UserManager.GetUserId(User);

        var isAuthorized = await AuthorizationService.AuthorizeAsync(User, MRegForm, RegFormOperations.Create);

        if (isAuthorized.Succeeded == false)
            return Forbid();

        Context.MRegForm.Add(MRegForm);
        await Context.SaveChangesAsync();

        return RedirectToPage("./Index");
    }

这是我的编辑OnPostAsync():

public async Task<IActionResult> OnPostAsync(int id)
    {
        var mRegForm = await Context.MRegForm.AsNoTracking().SingleOrDefaultAsync(m => m.MRegFormId == id);

        if (mRegForm == null)
            return NotFound();

        MRegForm.CreatorId = mRegForm.CreatorId;

        var isAuthorized = await AuthorizationService.AuthorizeAsync(User, MRegForm, RegFormOperations.Update);

        if (isAuthorized.Succeeded == false)
            return Forbid();

        MRegForm.Status = mRegForm.Status; // the Status is the current Status - Do Not Reset

        Context.Attach(MRegForm).State = EntityState.Modified;

        try
        {
            await Context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MRegFormExists(MRegForm.MRegFormId))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return RedirectToPage("./Index");
    }

    private bool MRegFormExists(int id)
    {
      return (Context.MRegForm?.Any(e => e.MRegFormId == id)).GetValueOrDefault();
    }
}
pexxcrt2

pexxcrt21#

您可以尝试从数据库中下载实体(如果存在)并对其进行更改,如果不存在,则创建新的实体。您的客户端始终可以在表单中创建新的MRegForm,但您需要在后面添加或更新。另一种选择是将现有的MRegForm传递到表单,客户端将看到并更改所有需要的属性。

public async Task AddOrUpdate(MRegForm input)
{

   var mRegForm = await Context.MRegForm
      .FirstOrDefaltAsync(x => x.FirstName == input.FirstName && x.LastName == input.LastName && x.DOB == input.YourDate);

   if(mRegForm != null)
   {
       //Make changes on mRegForm

       mRegForm.SomeProp = input.SomeProp,
       ...
   }
   else
   {
       var newMRegForm = new MRegForm
       {
          //Set all props you need
       }

       await this.Context.AddAsync(newMRegForm );
   }

   await this.Context.SaveCangesAsync();

}

相关问题