如何处理一对多关系中的可选外键约束错误

How to handle optional Foreign Key constraint error in One to Many relationship

我是 ASP.Net MVC 5 的初学者,目前遇到 Fluent API 问题。我有一个 Referral Class,它可以与 Coverletter class 建立一对多关系。有时 Rererral 行可能存在 w/o 求职信(我认为 0..*)。

流利API:

//// one cover letter can be there in many referral request
dBModelBuilder.Entity<CoverLetter>()
    .HasMany(u => u.Referrals)
    .WithOptional(u => u.CoverLetter)
    .HasForeignKey(u => u.CoverLetterId);

推荐模型:

public class Referral
{
    [Key]
    public int ReferralId { get; set; }
    // I added "?" to make FK Optional
    public int? CoverLetterId { get; set; }
    public virtual CoverLetter CoverLetter { get; set; }
}

ReferralViewModel:

public class ReferralViewModel
{
    public int ReferralViewModelId { get; set; }
    [Display(Name = "Cover Letter")]
    public int CoverLetterId { get; set; }
    public IEnumerable<CoverLetter> CoverLetters { get; set; }
}

控制器操作:

[HttpPost]
public ActionResult Create(ReferralViewModel viewModel)
{
    var candidateId = User.Identity.GetUserId();
    var referral = new Referral
    {
        CoverLetterId = viewModel.CoverLetterId
    };
   // I get exception here
    _context.Referrals.Add(referral);
    _context.SaveChanges();
    return RedirectToAction("ReferralCenter");
}

问题 当我没有 select 来自 UI 的任何求职信时,求职信 ID 来自我的 viewModel 的 0。而且我认为因为在 DB 中没有 ID 为 0 的求职信,所以我得到了 DB Contraint Exception。

异常:

{"The INSERT statement conflicted with the FOREIGN KEY constraint \"FK_dbo.Referrals_dbo.CoverLetters_CoverLetterId\". The conflict occurred in database \"aspnet-Bridge-20170730012232\", table \"dbo.CoverLetters\", column 'CoverLetterId'.\r\nThe statement has been terminated."}

为了使 FK 可选,我做了两个步骤

一个。添加 ”?”在模型中 属性

b。在 Fluent API.

中添加了 "HasOptional"

修复:

当我没有 select 任何 CoverlLetter 然后在提交表单时我希望 CoverLetter ID 为 NULL 而不是零。

更改控制器中的求职信 ID 分配

CoverLetterId = viewModel.CoverLetterId == 0 ? null : viewModel.CoverLetterId;

你也可以

public int CoverLetterId { get; set; }

改为 public int? CoverLetterId { get; set; }ReferralViewModel.

然后,在控制器中你将不得不使用额外的检查

CoverLetterId = viewModel.CoverLetterId.HasValue ? ((viewModel.CoverLetterId.Value == 0) ? null : viewModel.CoverLetterId.Value) : null

如果你知道你要在 HttpPost 中从前端传递 0,并且不会让 viewModel.CoverLetterId 取它的默认值,你可以使用。

CoverLetterId = (viewModel.CoverLetterId.Value == 0) ? null : viewModel.CoverLetterId.Value